Skip to content

Commit ff960e3

Browse files
committed
Document #[from]
1 parent df94656 commit ff960e3

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

README.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use thiserror::Error;
2727
#[derive(Error, Debug)]
2828
pub enum DataStoreError {
2929
#[error("data store disconnected")]
30-
Disconnect(#[source] io::Error),
30+
Disconnect(#[from] io::Error),
3131
#[error("the data for key `{0}` is not available")]
3232
Redaction(String),
3333
#[error("invalid header (expected {expected:?}, found {found:?})")]
@@ -78,9 +78,29 @@ pub enum DataStoreError {
7878
}
7979
```
8080

81+
- A `From` impl is generated for each variant containing a `#[from]` attribute.
82+
83+
Note that the variant must not contain any other fields beyond the source
84+
error and possibly a backtrace. A backtrace is captured from within the `From`
85+
impl if there is a field for it.
86+
87+
```rust
88+
#[derive(Error, Debug)]
89+
pub enum MyError {
90+
Io {
91+
#[from]
92+
source: io::Error,
93+
backtrace: Backtrace,
94+
},
95+
}
96+
```
97+
8198
- The Error trait's `source()` method is implemented to return whichever field
82-
has a `#[source]` attribute, if any. This is for identifying the underlying
83-
lower level error that caused your error.
99+
has a `#[source]` attribute or is named `source`, if any. This is for
100+
identifying the underlying lower level error that caused your error.
101+
102+
The `#[from]` attribute always implies that the same field is `#[source]`, so
103+
you don't ever need to specify both attributes.
84104

85105
Any error type that implements `std::error::Error` or dereferences to `dyn
86106
std::error::Error` will work as a source.
@@ -89,7 +109,7 @@ pub enum DataStoreError {
89109
#[derive(Error, Debug)]
90110
pub struct MyError {
91111
msg: String,
92-
#[source]
112+
#[source] // optional if field name is `source`
93113
source: anyhow::Error,
94114
}
95115
```

src/lib.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! #[derive(Error, Debug)]
1515
//! pub enum DataStoreError {
1616
//! #[error("data store disconnected")]
17-
//! Disconnect(#[source] io::Error),
17+
//! Disconnect(#[from] io::Error),
1818
//! #[error("the data for key `{0}` is not available")]
1919
//! Redaction(String),
2020
//! #[error("invalid header (expected {expected:?}, found {found:?})")]
@@ -67,9 +67,32 @@
6767
//! }
6868
//! ```
6969
//!
70+
//! - A `From` impl is generated for each variant containing a `#[from]`
71+
//! attribute.
72+
//!
73+
//! Note that the variant must not contain any other fields beyond the source
74+
//! error and possibly a backtrace. A backtrace is captured from within the
75+
//! `From` impl if there is a field for it.
76+
//!
77+
//! ```rust
78+
//! # const IGNORE: &str = stringify! {
79+
//! #[derive(Error, Debug)]
80+
//! pub enum MyError {
81+
//! Io {
82+
//! #[from]
83+
//! source: io::Error,
84+
//! backtrace: Backtrace,
85+
//! },
86+
//! }
87+
//! # };
88+
//! ```
89+
//!
7090
//! - The Error trait's `source()` method is implemented to return whichever
71-
//! field has a `#[source]` attribute, if any. This is for identifying the
72-
//! underlying lower level error that caused your error.
91+
//! field has a `#[source]` attribute or is named `source`, if any. This is
92+
//! for identifying the underlying lower level error that caused your error.
93+
//!
94+
//! The `#[from]` attribute always implies that the same field is `#[source]`,
95+
//! so you don't ever need to specify both attributes.
7396
//!
7497
//! Any error type that implements `std::error::Error` or dereferences to `dyn
7598
//! std::error::Error` will work as a source.
@@ -81,7 +104,7 @@
81104
//! #[derive(Error, Debug)]
82105
//! pub struct MyError {
83106
//! msg: String,
84-
//! #[source]
107+
//! #[source] // optional if field name is `source`
85108
//! source: anyhow::Error,
86109
//! }
87110
//! #

0 commit comments

Comments
 (0)