Skip to content

Commit a03d6d6

Browse files
authored
Merge pull request #402 from dtolnay/fromboxed
Add Error::from_boxed with documentation about bidirectional `?`
2 parents ffecefc + 52e4abb commit a03d6d6

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

src/error.rs

+61
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,67 @@ impl Error {
8585
Error::construct_from_adhoc(message, backtrace!())
8686
}
8787

88+
/// Construct an error object from a type-erased standard library error.
89+
///
90+
/// This is mostly useful for interop with other error libraries.
91+
///
92+
/// # Example
93+
///
94+
/// Here is a skeleton of a library that provides its own error abstraction.
95+
/// The pair of `From` impls provide bidirectional support for `?`
96+
/// conversion between `Report` and `anyhow::Error`.
97+
///
98+
/// ```
99+
/// use std::error::Error as StdError;
100+
///
101+
/// pub struct Report {/* ... */}
102+
///
103+
/// impl<E> From<E> for Report
104+
/// where
105+
/// E: Into<anyhow::Error>,
106+
/// Result<(), E>: anyhow::Context<(), E>,
107+
/// {
108+
/// fn from(error: E) -> Self {
109+
/// let anyhow_error: anyhow::Error = error.into();
110+
/// let boxed_error: Box<dyn StdError + Send + Sync + 'static> = anyhow_error.into();
111+
/// Report::from_boxed(boxed_error)
112+
/// }
113+
/// }
114+
///
115+
/// impl From<Report> for anyhow::Error {
116+
/// fn from(report: Report) -> Self {
117+
/// let boxed_error: Box<dyn StdError + Send + Sync + 'static> = report.into_boxed();
118+
/// anyhow::Error::from_boxed(boxed_error)
119+
/// }
120+
/// }
121+
///
122+
/// impl Report {
123+
/// fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self {
124+
/// todo!()
125+
/// }
126+
/// fn into_boxed(self) -> Box<dyn StdError + Send + Sync + 'static> {
127+
/// todo!()
128+
/// }
129+
/// }
130+
///
131+
/// // Example usage: can use `?` in both directions.
132+
/// fn a() -> anyhow::Result<()> {
133+
/// b()?;
134+
/// Ok(())
135+
/// }
136+
/// fn b() -> Result<(), Report> {
137+
/// a()?;
138+
/// Ok(())
139+
/// }
140+
/// ```
141+
#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
142+
#[cold]
143+
#[must_use]
144+
pub fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self {
145+
let backtrace = backtrace_if_absent!(&*boxed_error);
146+
Error::construct_from_boxed(boxed_error, backtrace)
147+
}
148+
88149
#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
89150
#[cold]
90151
pub(crate) fn construct_from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self

0 commit comments

Comments
 (0)