1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//! This library provides a convenient derive macro for the standard library's //! [`std::error::Error`] trait. //! //! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html //! //! <br> //! //! # Example //! //! ```rust //! # use std::io; //! 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, //! } //! ``` //! //! <br> //! //! # 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)` //! //! You may alternatively write out the full format args yourself, using //! arbitrary expressions. //! //! When providing your own format args, the shorthand does not kick in so you //! need to specify `.var` in the argument list to refer to named fields and //! `.0` to refer to tuple fields. //! //! ```rust //! # use thiserror::Error; //! # //! #[derive(Error, Debug)] //! pub enum Error { //! #[error("invalid rdo_lookahead_frames {} (expected < {})", .0, i32::max_value())] //! InvalidLookahead(i32), //! } //! ``` //! //! - 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. //! //! ```rust //! # const IGNORE: &str = stringify! { //! #[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 named `source`, 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 to `dyn //! std::error::Error` will work as a source. //! //! ```rust //! # use std::fmt::{self, Display}; //! # use thiserror::Error; //! # //! #[derive(Error, Debug)] //! pub struct MyError { //! msg: String, //! #[source] // optional if field name is `source` //! source: anyhow::Error, //! } //! # //! # impl Display for MyError { //! # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { //! # unimplemented!() //! # } //! # } //! ``` //! //! - The Error trait's `backtrace()` method is implemented to return whichever //! field has a type named `Backtrace`, if any. //! //! ```rust //! # const IGNORE: &str = stringify! { //! 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. //! //! [`anyhow`]: https://github.com/dtolnay/anyhow mod aserror; pub use thiserror_impl::*; // Not public API. #[doc(hidden)] pub mod private { pub use crate::aserror::AsDynError; }