← Back to Rust Course | Chapter 10: Error Handling | Lesson 4 of 6

Custom Error Types बनाना

कभी-कभी आप अपना खुद का error message design करते हैं, ताकि आपका program बिल्कुल अपने शब्दों में explain कर सके कि क्या गलत हुआ।
Syntax
rust
#[derive(Debug)]
enum NameError {
    Variant(Type),
}

impl std::fmt::Display for NameError {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "message")
    }
}

impl std::error::Error for NameError {}

Defining a Custom Error Enum

एक custom error type आमतौर पर एक enum होता है जो हर distinct तरीके को list करता है जिससे एक operation fail हो सकता है, callers को सिर्फ एक generic string के बजाय structured information देते हुए।

उदाहरण: Defining a Custom Error Enum

markup
// Auto-generate #[derive(Debug)] for the type below
#[derive(Debug)]
// Define an enum `MathError` listing its possible variants
enum MathError {
    DivideByZero,
    NegativeSquareRoot,
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `err`, set to `MathError::DivideByZero`
    let err = MathError::DivideByZero;
    // Print "{:?}" to the console, substituting in `err` (with a trailing newline)
    println!("{:?}", err);
}

Returning a Custom Error from a Function

Functions custom error type उपयोग करके Result<T, MyError> return कर सकते हैं, compiler को यह enforce करने देते हुए कि हर failure case enum में represented है।

उदाहरण: Returning a Custom Error from a Function

markup
// Auto-generate #[derive(Debug)] for the type below
#[derive(Debug)]
// Define an enum `MathError` listing its possible variants
enum MathError {
    DivideByZero,
}

// Define the function `divide` taking `a`, `b` and returning a `Result<f64, MathError>`
fn divide(a: f64, b: f64) -> Result<f64, MathError> {
    // Check whether `b == 0.0`
    if b == 0.0 {
        Err(MathError::DivideByZero)
    // Otherwise, run this branch
    } else {
        Ok(a / b)
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Print "{:?}" to the console, substituting in `divide(10.0, 0.0)` (with a trailing newline)
    println!("{:?}", divide(10.0, 0.0));
}

Implementing Display for Readable Messages

किसी custom error type के लिए std::fmt::Display implement करना इसे {} से print करते समय सिर्फ raw Debug output के बजाय एक साफ़, human-readable message देता है।

उदाहरण: Implementing Display for Readable Messages

markup
// Bring `std::fmt` into scope
use std::fmt;

// Auto-generate #[derive(Debug)] for the type below
#[derive(Debug)]
// Define an enum `MathError` listing its possible variants
enum MathError {
    DivideByZero,
}

// Implement methods on `fmt`
impl fmt::Display for MathError {
    // Define the function `fmt` taking `&self`, `f` and returning a `fmt::Result`
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Match on `self` and branch by pattern
        match self {
            MathError::DivideByZero => write!(f, "cannot divide by zero"),
        }
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `err`, set to `MathError::DivideByZero`
    let err = MathError::DivideByZero;
    // Print "{}" to the console, substituting in `err` (with a trailing newline)
    println!("{}", err);
}

Matching on a Custom Error

चूंकि एक custom error एक enum है, callers हर specific failure kind पर अलग response देने के लिए इस पर match कर सकते हैं, सिर्फ एक single generic error message रखने के बजाय।

उदाहरण: Matching on a Custom Error

markup
// Auto-generate #[derive(Debug)] for the type below
#[derive(Debug)]
// Define an enum `MathError` listing its possible variants
enum MathError {
    DivideByZero,
    NegativeSquareRoot,
}

// Define the function `check` taking `n` and returning a `Result<f64, MathError>`
fn check(n: f64) -> Result<f64, MathError> {
    // Check whether `n < 0.0`
    if n < 0.0 {
        Err(MathError::NegativeSquareRoot)
    // Otherwise, run this branch
    } else {
        Ok(n.sqrt())
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Match on `check(-4.0)` and branch by pattern
    match check(-4.0) {
        Ok(v) => println!("Root: {}", v),
        Err(MathError::NegativeSquareRoot) => println!("Cannot take root of negative number"),
        Err(MathError::DivideByZero) => println!("Divide by zero"),
    }
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक proper enum के बजाय हर error के लिए String उपयोग करना, callers की specific failure kinds पर match करने की क्षमता खोते हुए।
  2. std::fmt::Display (और अक्सर std::error::Error) implement करना भूल जाना ताकि custom error type nicely print हो और दूसरे error-handling code के साथ interoperate करे।
  3. एक custom error enum define करना लेकिन कभी Debug derive या implement न करना, जो ज़्यादातर error-handling code expect करता है।
चैप्टर सारांश
  • एक custom error type आमतौर पर हर distinct तरह की failure के लिए एक variant वाला enum है।
  • std::fmt::Display implement करना error type को एक readable, user-facing message देता है।
  • std::error::Error implement करना आपके custom error को wider Rust error-handling ecosystem के साथ interoperate करने देता है।
  • Custom error types callers को सिर्फ एक generic message string के बजाय specific failure kinds पर match करने देते हैं।
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.