[−][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::Error
by 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
Display
impl 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
.var
and 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
From
impl 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
From
impl 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::Error
or dereferences todyn std::error::Error
will 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
anyhow
library for a convenient single error type to use in application code.
Derive Macros
Error |