In this lesson, you will learn how to create custom error types that integrate seamlessly with Rust’s ecosystem by implementing the std::error::Error trait.
The Problem with Basic Errors
When writing a domain-specific library, you often need to represent several failure modes (e.g., DatabaseError, ValidationError). If you only return a String or a simple enum, you lose the ability to treat your errors as standard parts of the Rust language. By implementing the Error trait, you allow your custom errors to work with the ? operator, dynamic dispatch, and polymorphic error reporting.
Implementing the Trait
To make a type act as a "first-class" error, you must implement Debug and Display (which you learned in lesson 7), and then the std::error::Error trait.
use std::fmt;
#[derive(Debug)]
pub enum MyDomainError {
ConnectionFailed(String),
InvalidInput,
}
impl fmt::Display for MyDomainError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ConnectionFailed(msg) => write!(f, "Connection issue: {}", msg),
Self::InvalidInput => write!(f, "The input provided was invalid"),
}
}
}
// The Error trait acts as a marker for error types
impl std::error::Error for MyDomainError {}
Why Do This?
Because MyDomainError now implements Error, you can use it in functions that return Result<T, Box<dyn std::error::Error>>. This is the hallmark of polymorphic error reporting: you can write a function that handles any error type that implements the Error trait, rather than being locked into one specific enum.
When you pair this with the From trait (lesson 6), you can use the ? operator to automatically convert your local domain errors into a broader error type, simplifying your control flow significantly. Your custom errors are no longer just strings or objects; they are now participants in the standard Rust error-handling pipeline.
Key Takeaway: Implementing the Error trait for your types enables them to participate in Rust’s standardized, polymorphic error propagation system, making your library code robust and idiomatic.