thiserror
thiserror derives Display, Error, and From for error enums - standard for library crates.
Search across all documentation pages
thiserror derives Display, Error, and From for error enums - standard for library crates.
[dependencies]
thiserror = "2"use thiserror::Error;
#[derive(Debug, Error)]
enum ConfigError {
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("invalid port: {0}")]
Parse(#[from] std::num::ParseIntError),
}When to reach for this: Public library error types with minimal boilerplate.
fn load(path: &str) -> Result<u16, ConfigError> {
let s = std::fs::read_to_string(path)?;
Ok(s.trim().parse()?)
}
fn main() {
if let Err(e) = load("port.txt") {
eprintln!("{e}");
if let Some(src) = std::error::Error::source(&e) {
eprintln!("caused by: {src}");
}
}
}What this demonstrates:
#[from] generates From impls#[error("...")] formats DisplayError::source chains underlying errorsSupports #[error(transparent)] for wrapper variants and custom backtrace fields (optional).
#[error] is semver for human readers. Fix: Treat messages as API carefully.From for one variant - Manual impl needed. Fix: Add #[from] or hand impl.map_err(Into::into).| Alternative | Use When | Don't Use When |
|---|---|---|
Manual Error impl | No proc-macro dep | thiserror available |
snafu | Structured context attrs | Team standard is thiserror |
anyhow | Application | Library public API |
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