Custom Error Types
Library crates define error enums wrapping underlying failures, implement std::error::Error, Display, and From for ergonomic ?.
Search across all documentation pages
Library crates define error enums wrapping underlying failures, implement std::error::Error, Display, and From for ergonomic ?.
use std::fmt;
#[derive(Debug)]
enum DataError {
Io(std::io::Error),
Parse(std::num::ParseIntError),
}
impl fmt::Display for DataError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DataError::Io(e) => write!(f, "io: {e}"),
DataError::Parse(e) => write!(f, "parse: {e}"),
}
}
}
impl std::error::Error for DataError {}
impl From<std::io::Error> for DataError {
fn from(e: std::io::Error) -> Self { DataError::Io(e) }
}When to reach for this: Public libraries exposing stable error types consumers can match.
fn load_port(path: &str) -> Result<u16, DataError> {
let s = std::fs::read_to_string(path)?;
let p = s.trim().parse()?;
Ok(p)
}With From for ParseIntError added similarly.
What this demonstrates:
? converts automaticallymatch on DataError variantsImplement source() on Error to chain causes. Use #[non_exhaustive] on public error enums for semver.
From - ? fails. Fix: derive or impl From.Arc source or boxed inner error.Send/Sync - Breaks threads. Fix: Ensure wrapped errors are Send + Sync.| Alternative | Use When | Don't Use When |
|---|---|---|
thiserror | Derive boilerplate | Tiny internal crate |
anyhow | Application flexibility | Stable library API |
Box<dyn Error> | Quick binary | Typed matching needed |
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026