thiserror/
lib.rs

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