Custom Errors in Rust
It’s possible to use custom types as errors by implementing the Error trait on them. Here’s an example that uses a custom type to explicitly represent an argument error.
use std::fmt;
use std::error::Error;
// A custom error type usually has the suffix "Error".
#[derive(Debug)]
struct ArgError {
arg: i32,
message: String,
}
// Implementing the Display trait for our custom error
impl fmt::Display for ArgError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} - {}", self.arg, self.message)
}
}
// Implementing the Error trait for our custom error
impl Error for ArgError {}
fn f(arg: i32) -> Result<i32, ArgError> {
if arg == 42 {
// Return our custom error.
Err(ArgError { arg, message: String::from("can't work with it") })
} else {
Ok(arg + 3)
}
}
fn main() {
// The `downcast_ref` method is similar to `errors.As` in Go.
// It attempts to downcast the error to a concrete type.
let result = f(42);
if let Err(e) = result {
if let Some(ae) = e.downcast_ref::<ArgError>() {
println!("{}", ae.arg);
println!("{}", ae.message);
} else {
println!("err doesn't match ArgError");
}
}
}In this Rust version:
We define a custom
ArgErrorstruct that implements both theDisplayandErrortraits. This is equivalent to implementing theerrorinterface in Go.The
ffunction returns aResult<i32, ArgError>instead of(int, error). This is Rust’s idiomatic way of handling errors.In the
mainfunction, we use pattern matching (if let) to handle theResultreturned byf. This is similar to error checking in Go.To check if the error is of our custom type, we use the
downcast_refmethod, which is similar toerrors.Asin Go. It attempts to downcast the error to a concrete type.
To run the program:
$ rustc custom_errors.rs
$ ./custom_errors
42
can't work with itThis example demonstrates how to create and use custom error types in Rust, which provides a similar level of flexibility for error handling as Go.