Error handling in Rust:
Rust and compilation errors are going hand-in-hand. The compiler of Rust is very strict in their grammar. Although, in the beginning, it feels very troublesome to see compiler complaining about everything, as time passes and your familiarity with Rust increases its becomes your biggest companion and will always help in pinpointing and resolving major parts of the problem.
This write-up particularly talks about how to replace unwrap, expect and panic with Result<_, Err> and handle possible failed scenarios for production code.
Unwrap - Unwraps a result, yielding the content of an Ok.
Panics if the value is an Err, with a panic message provided by the Err's value.
let code_value = self.get_code().unwrap();
Let's handle unwrap with a more logical and programmable way.
let code_value = match self.get_code() {
Ok(v) => v,
Err(e) => {
return Err(Error::invalid(format!(
"Invalid code: {}",
e
)))
},
};
Expect - Unwraps a result, yielding the content of an Ok.
Panics if the value is an Err, with a panic message including the passed message, and the other
content of the Err.
let n = s.trim().parse::<usize>().expect(&format!(
"Fatal when converting into usize, str = {}",
s.trim()
));
Let's handle expect with a more logical and programmable way.
let n = match s.trim().parse::<usize>() {
Ok(v) => v,
Err(s) => {
error!("Fatal when converting into usize, str = {}", s);
return Err(());
},
};
Panic - Panic is more suitable in situations where the program reaches in an unrecoverable state. But, it is not a good idea to decide the program unrecoverable state on behalf of the calling method. Instead, returning
Result<_, Err> value will give the calling method an option to make a decision.
panic!("Error: missing arguments, len = {}", args.len());
Let's return a result to the calling code and handle the panic scenario.
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("Error: missing arguments, len = {}", args.len()),
));