Skip to main content

thiserror/
lib.rs

1//! A convenient derive macro for the standard library's [`std::error::Error`]
2//! and [`core::error::Error`] traits.
3//!
4//! # Example
5//!
6//! ```rust
7//! # use std::io;
8//! use thiserror::Error;
9//!
10//! #[derive(Error, Debug)]
11//! pub enum DataStoreError {
12//!     #[error("data store disconnected")]
13//!     Disconnect(#[from] io::Error),
14//!     #[error("the data for key `{0}` is not available")]
15//!     Redaction(String),
16//!     #[error("invalid header (expected {expected:?}, found {found:?})")]
17//!     InvalidHeader {
18//!         expected: String,
19//!         found: String,
20//!     },
21//!     #[error("unknown data store error")]
22//!     Unknown,
23//! }
24//! ```
25//!
26//! # Details
27//!
28//! - Thiserror deliberately does not appear in your public API. You get the
29//!   same thing as if you had written an implementation of
30//!   [`std::error::Error`] by hand, and switching from handwritten impls to
31//!   thiserror or vice versa is not a breaking change.
32//!
33//! - Errors may be enums, structs with named fields, tuple structs, or unit
34//!   structs.
35//!
36//! - A [`Display`] impl is generated for your error if you provide
37//!   `#[error("...")]` messages on the struct or each variant of your enum, as
38//!   shown above in the example.
39//!
40//!   The messages support a shorthand for interpolating fields from the error.
41//!
42//!     - `#[error("{var}")]` ⟶ `write!("{}", self.var)`
43//!     - `#[error("{0}")]` ⟶ `write!("{}", self.0)`
44//!     - `#[error("{var:?}")]` ⟶ `write!("{:?}", self.var)`
45//!     - `#[error("{0:?}")]` ⟶ `write!("{:?}", self.0)`
46//!
47//!   These shorthands can be used together with any additional format args,
48//!   which may be arbitrary expressions. For example:
49//!
50//!   ```rust
51//!   # use core::i32;
52//!   # use thiserror::Error;
53//!   #
54//!   #[derive(Error, Debug)]
55//!   pub enum Error {
56//!       #[error("invalid rdo_lookahead_frames {0} (expected < {max})", max = i32::MAX)]
57//!       InvalidLookahead(u32),
58//!   }
59//!   ```
60//!
61//!   If one of the additional expression arguments needs to refer to a field of
62//!   the struct or enum, then refer to named fields as `.var` and tuple fields
63//!   as `.0`.
64//!
65//!   ```rust
66//!   # use thiserror::Error;
67//!   #
68//!   # fn first_char(s: &String) -> char {
69//!   #     s.chars().next().unwrap()
70//!   # }
71//!   #
72//!   # #[derive(Debug)]
73//!   # struct Limits {
74//!   #     lo: usize,
75//!   #     hi: usize,
76//!   # }
77//!   #
78//!   #[derive(Error, Debug)]
79//!   pub enum Error {
80//!       #[error("first letter must be lowercase but was {:?}", first_char(.0))]
81//!       WrongCase(String),
82//!       #[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
83//!       OutOfBounds { idx: usize, limits: Limits },
84//!   }
85//!   ```
86//!
87//! - A [`From`] impl is generated for each variant that contains a `#[from]`
88//!   attribute.
89//!
90//!   The variant using `#[from]` must not contain any other fields beyond the
91//!   source error (and possibly a backtrace &mdash; see below). Usually
92//!   `#[from]` fields are unnamed, but `#[from]` is allowed on a named field
93//!   too.
94//!
95//!   ```rust
96//!   # use core::fmt::{self, Display};
97//!   # use std::io;
98//!   # use thiserror::Error;
99//!   #
100//!   # mod globset {
101//!   #     #[derive(thiserror::Error, Debug)]
102//!   #     #[error("...")]
103//!   #     pub struct Error;
104//!   # }
105//!   #
106//!   #[derive(Error, Debug)]
107//!   pub enum MyError {
108//!       Io(#[from] io::Error),
109//!       Glob(#[from] globset::Error),
110//!   }
111//!   #
112//!   # impl Display for MyError {
113//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
114//!   #         unimplemented!()
115//!   #     }
116//!   # }
117//!   ```
118//!
119//! - The Error trait's [`source()`] method is implemented to return whichever
120//!   field has a `#[source]` attribute or is named `source`, if any. This is
121//!   for identifying the underlying lower level error that caused your error.
122//!
123//!   The `#[from]` attribute always implies that the same field is `#[source]`,
124//!   so you don't ever need to specify both attributes.
125//!
126//!   Any error type that implements `std::error::Error` or dereferences to `dyn
127//!   std::error::Error` will work as a source.
128//!
129//!   ```rust
130//!   # use core::fmt::{self, Display};
131//!   # use thiserror::Error;
132//!   #
133//!   #[derive(Error, Debug)]
134//!   pub struct MyError {
135//!       msg: String,
136//!       #[source]  // optional if field name is `source`
137//!       source: anyerr::Error,
138//!   }
139//!   #
140//!   # impl Display for MyError {
141//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
142//!   #         unimplemented!()
143//!   #     }
144//!   # }
145//!   ```
146//!
147//! - The Error trait's [`provide()`] method is implemented to provide whichever
148//!   field has a type named `Backtrace`, if any, as a
149//!   [`std::backtrace::Backtrace`]. Using `Backtrace` in errors requires a
150//!   nightly compiler.
151//!
152//!   ```rust
153//!   # const IGNORE: &str = stringify! {
154//!   use std::backtrace::Backtrace;
155//!
156//!   #[derive(Error, Debug)]
157//!   pub struct MyError {
158//!       msg: String,
159//!       backtrace: Backtrace,  // automatically detected
160//!   }
161//!   # };
162//!   ```
163//!
164//! - If a field is both a source (named `source`, or has `#[source]` or
165//!   `#[from]` attribute) *and* is marked `#[backtrace]`, then the Error
166//!   trait's [`provide()`] method is forwarded to the source's `provide` so
167//!   that both layers of the error share the same backtrace. The `#[backtrace]`
168//!   attribute requires a nightly compiler.
169//!
170//!   ```rust
171//!   # const IGNORE: &str = stringify! {
172//!   #[derive(Error, Debug)]
173//!   pub enum MyError {
174//!       Io {
175//!           #[backtrace]
176//!           source: io::Error,
177//!       },
178//!   }
179//!   # };
180//!   ```
181//!
182//! - For variants that use `#[from]` and also contain a `Backtrace` field, a
183//!   backtrace is captured from within the `From` impl.
184//!
185//!   ```rust
186//!   # const IGNORE: &str = stringify! {
187//!   #[derive(Error, Debug)]
188//!   pub enum MyError {
189//!       Io {
190//!           #[from]
191//!           source: io::Error,
192//!           backtrace: Backtrace,
193//!       },
194//!   }
195//!   # };
196//!   ```
197//!
198//! - Errors may use `error(transparent)` to forward the source and [`Display`]
199//!   methods straight through to an underlying error without adding an
200//!   additional message. This would be appropriate for enums that need an
201//!   "anything else" variant.
202//!
203//!   ```
204//!   # use thiserror::Error;
205//!   #
206//!   #[derive(Error, Debug)]
207//!   pub enum MyError {
208//!       # /*
209//!       ...
210//!       # */
211//!
212//!       #[error(transparent)]
213//!       Other(#[from] anyerr::Error),  // source and Display delegate to anyerr::Error
214//!   }
215//!   ```
216//!
217//!   Another use case is hiding implementation details of an error
218//!   representation behind an opaque error type, so that the representation is
219//!   able to evolve without breaking the crate's public API.
220//!
221//!   ```
222//!   # use thiserror::Error;
223//!   #
224//!   // PublicError is public, but opaque and easy to keep compatible.
225//!   #[derive(Error, Debug)]
226//!   #[error(transparent)]
227//!   pub struct PublicError(#[from] ErrorRepr);
228//!
229//!   impl PublicError {
230//!       // Accessors for anything we do want to expose publicly.
231//!   }
232//!
233//!   // Private and free to change across minor version of the crate.
234//!   #[derive(Error, Debug)]
235//!   enum ErrorRepr {
236//!       # /*
237//!       ...
238//!       # */
239//!   }
240//!   ```
241//!
242//! - See also the [`anyerr`] library for a convenient single error type to use
243//!   in application code.
244//!
245//! [`anyerr`]: https://github.com/rust-stdx/stdx
246//! [`source()`]: std::error::Error::source
247//! [`provide()`]: std::error::Error::provide
248//! [`Display`]: std::fmt::Display
249
250#![no_std]
251#![allow(
252    clippy::elidable_lifetime_names,
253    clippy::module_name_repetitions,
254    clippy::needless_lifetimes,
255    clippy::return_self_not_must_use,
256    clippy::wildcard_imports
257)]
258#![cfg_attr(error_generic_member_access, feature(error_generic_member_access))]
259
260#[cfg(all(thiserror_nightly_testing, not(error_generic_member_access)))]
261compile_error!("Build script probe failed to compile.");
262
263#[cfg(feature = "std")]
264extern crate std;
265#[cfg(feature = "std")]
266extern crate std as core;
267
268mod aserror;
269mod display;
270#[cfg(error_generic_member_access)]
271mod provide;
272mod var;
273
274pub use thiserror_impl::*;
275
276mod private;
277
278include!(concat!(env!("OUT_DIR"), "/private.rs"));