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());
}