[−][src]Crate thiserror
This library provides a convenient derive macro for the standard library's
std::error::Error trait.
Example
use thiserror::Error; #[derive(Error, Debug)] pub enum DataStoreError { #[error("data store disconnected")] Disconnect(#[from] io::Error), #[error("the data for key `{0}` is not available")] Redaction(String), #[error("invalid header (expected {expected:?}, found {found:?})")] InvalidHeader { expected: String, found: String, }, #[error("unknown data store error")] Unknown, }
Details
-
Thiserror deliberately does not appear in your public API. You get the same thing as if you had written an implementation of
std::error::Errorby hand, and switching from handwritten impls to thiserror or vice versa is not a breaking change. -
Errors may be enums, structs with named fields, tuple structs, or unit structs.
-
A
Displayimpl is generated for your error if you provide#[error("...")]messages on the struct or each variant of your enum, as shown above in the example.The messages support a shorthand for interpolating fields from the error.
#[error("{var}")]⟶write!("{}", self.var)#[error("{0}")]⟶write!("{}", self.0)#[error("{var:?}")]⟶write!("{:?}", self.var)#[error("{0:?}")]⟶write!("{:?}", self.0)
These shorthands can be used together with any additional format args, which may be arbitrary expressions. For example:
#[derive(Error, Debug)] pub enum Error { #[error("invalid rdo_lookahead_frames {0} (expected < {})", i32::max_value())] InvalidLookahead(u32), }
If one of the additional expression arguments needs to refer to a field of the struct or enum, then refer to named fields as
.varand tuple fields as.0.#[derive(Error, Debug)] pub enum Error { #[error("first letter must be lowercase but was {:?}", first_char(.0))] WrongCase(String), #[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)] OutOfBounds { idx: usize, limits: Limits }, }
-
A
Fromimpl is generated for each variant containing a#[from]attribute.Note that the variant must not contain any other fields beyond the source error and possibly a backtrace. A backtrace is captured from within the
Fromimpl if there is a field for it.#[derive(Error, Debug)] pub enum MyError { Io { #[from] source: io::Error, backtrace: Backtrace, }, }
-
The Error trait's
source()method is implemented to return whichever field has a#[source]attribute or is namedsource, if any. This is for identifying the underlying lower level error that caused your error.The
#[from]attribute always implies that the same field is#[source], so you don't ever need to specify both attributes.Any error type that implements
std::error::Erroror dereferences todyn std::error::Errorwill work as a source.#[derive(Error, Debug)] pub struct MyError { msg: String, #[source] // optional if field name is `source` source: anyhow::Error, }
-
The Error trait's
backtrace()method is implemented to return whichever field has a type namedBacktrace, if any.use std::backtrace::Backtrace; #[derive(Error, Debug)] pub struct MyError { msg: String, backtrace: Backtrace, // automatically detected }
-
See also the
anyhowlibrary for a convenient single error type to use in application code.
Derive Macros
| Error |