How to Handle Multiple Error Types in One Function

Handle multiple error types in Rust by defining a custom enum and implementing the Error trait to unify failure cases.

Define a custom error enum listing all possible failures and implement the std::error::Error trait to handle them uniformly.

use std::fmt;
use std::thread;
use std::sync::Mutex;

#[derive(Debug)]
enum AppError {
    ThreadJoinError,
    LockError,
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AppError::ThreadJoinError => write!(f, "Thread failed to join"),
            AppError::LockError => write!(f, "Failed to acquire lock"),
        }
    }
}

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

fn main() {
    let counter = Mutex::new(0);
    let mut handles = vec![];

    for _ in 0..10 {
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().map_err(|_| AppError::ThreadJoinError)?;
    }

    println!("Result: {}", *counter.lock().unwrap());
}