Rust error handling

Created By: chatGPT

Error handling in Rust is an important concept that allows developers to manage errors gracefully. Rust provides two primary mechanisms for error handling through the Result and Option types. The Result type is commonly used for functions that can return an error, while Option is used for representing nullable values. Below, we will discuss both mechanisms in detail.
// Using Result

fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Cannot divide by zero."))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(4.0, 2.0) {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
}
In the above code, we define a divide function that returns a Result<f64, String>. It checks if the divisor is zero and returns an error if so. Otherwise, it returns the division result. In the main function, we handle both possibilities: a successful result and an error.
// Using Option

fn find_item(vec: &Vec<i32>, item: i32) -> Option<usize> {
    for (index, &value) in vec.iter().enumerate() {
        if value == item {
            return Some(index);
        }
    }
    None
}

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    match find_item(&numbers, 3) {
        Some(index) => println!("Item found at index: {}", index),
        None => println!("Item not found."),
    }
}
When using Option, we define a find_item function that searches for an item in a vector and returns its index if found. If the item is not found, it returns None. In the main function, we again use pattern matching to handle both scenarios. Pattern matching is a powerful feature in Rust that offers a concise and expressive way to deal with different outcomes.
// Error handling with ? operator

fn read_file(file_path: &str) -> Result<String, std::io::Error> {
    let content = std::fs::read_to_string(file_path)?;
    Ok(content)
}

fn main() {
    match read_file("example.txt") {
        Ok(content) => println!("File content: {}", content),
        Err(e) => println!("Error reading file: {}", e),
    }
}
In the example above, we use the ? operator to simplify error handling. The read_file function reads the content of a file and automatically returns an error if it occurs. This removes the need for verbose error handling code. The ? operator is very useful when dealing with propagating errors, making the code cleaner and more readable.
// Custom error types

use std::fmt;

#[derive(Debug)]
struct MyError {
    details: String,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.details)
    }
}

impl std::error::Error for MyError {}
You can also define your own custom error types to represent specific errors in your application. In the example above, we create a MyError struct that implements the Debug, Display, and Error traits, allowing it to be used in the same way as standard error types in Rust. This is a powerful feature that gives you full control over error representation and handling.
// Error handling with a custom type

fn perform_action() -> Result<(), MyError> {
    Err(MyError { details: String::from("An error occurred") })
}

fn main() {
    match perform_action() {
        Ok(_) => println!("Action performed successfully."),
        Err(e) => println!("Action failed: {}", e),
    }
}
Introduction And SetupVariablesData TypesImmutableMutableIntegerFloating PointBooleanCharacterStringArrayTupleVectorSliceHashmapMethodFunctionSyntaxBlock ExpressionIf ExpressionLoopWhile LoopFor LoopMatch ExpressionPattern MatchingOwnershipBorrowingReferencesLifetimesEnumsStructsTraitsImpl BlockGenericType AliasPanicResultOptionError HandlingUnwrappingVariantClosureIteratorAsyncAwaitTrait ObjectModuleCrateAttributeMacroCommentSingle Line CommentMulti Line CommentDoc CommentCargoFormattingOwnership RulesType InferenceShadowingOperatorArithmetic OperatorComparison OperatorLogical OperatorBitwise OperatorAs KeywordConstStaticCopy TraitClone TraitUnsafe CodeFfiCargo ManagementTraits BoundsMatch ArmDerived TraitsClosure CaptureSplit_atIterFilterMapCollectFrom_iterTuple StructUnit TypeNaming ConventionsModule SystemVisibilityPrivatePublicCrate RootUnix Specific FeaturesWindows Specific Features