thiserror/
lib.rs

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