thiserror
thiserror derives Display, Error, and From for error enums - standard for library crates.
Recipe
[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.
Working Example
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]generatesFromimpls#[error("...")]formatsDisplayError::sourcechains underlying errors
Deep Dive
Supports #[error(transparent)] for wrapper variants and custom backtrace fields (optional).
Gotchas
- thiserror in binaries only - Overkill vs anyhow. Fix: anyhow for apps, thiserror for libs.
- Display format drift - Changing
#[error]is semver for human readers. Fix: Treat messages as API carefully. - Missing
Fromfor one variant - Manual impl needed. Fix: Add#[from]or hand impl. - Large derive on many variants - Compile time. Fix: Split error hierarchies.
- Combining with anyhow - Convert at boundary:
map_err(Into::into).
Alternatives
| 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 |
FAQs
thiserror 1 vs 2?
Pin 2.x for new projects per manifest.no_std?
thiserror supports no_std with features.backtrace field?
Opt-in with `Backtrace` type in enum.transparent variant?
Forwards Display/source to inner.enum vs struct?
Enum variants most common pattern.combine errors?
Multiple `#[from]` variants.serde on errors?
Usually skip serializing errors.clippy?
Compatible with standard lints.wasm?
Works in wasm32 targets.vs anyhow derive?
anyhow is not for public error enums.Related
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+.