Skip to main content

anyhow/
error.rs

1use crate::backtrace::Backtrace;
2use crate::chain::Chain;
3#[cfg(error_generic_member_access)]
4use crate::nightly::{self, Request};
5#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
6use crate::ptr::Mut;
7use crate::ptr::{Own, Ref};
8use crate::{Error, StdError};
9use alloc::boxed::Box;
10use core::any::TypeId;
11use core::fmt::{self, Debug, Display};
12use core::mem::ManuallyDrop;
13#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
14use core::ops::{Deref, DerefMut};
15use core::panic::{RefUnwindSafe, UnwindSafe};
16use core::ptr;
17use core::ptr::NonNull;
18
19impl Error {
20    /// Create a new error object from any error type.
21    ///
22    /// The error type must be threadsafe and `'static`, so that the `Error`
23    /// will be as well.
24    ///
25    /// If the error type does not provide a backtrace, a backtrace will be
26    /// created here to ensure that a backtrace exists.
27    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
28    #[cold]
29    #[must_use]
30    pub fn new<E>(error: E) -> Self
31    where
32        E: StdError + Send + Sync + 'static,
33    {
34        let backtrace = match crate::nightly::request_ref_backtrace(&error as &dyn core::error::Error)
    {
    Some(_) => None,
    None => Some(std::backtrace::Backtrace::capture()),
}backtrace_if_absent!(&error);
35        Error::construct_from_std(error, backtrace)
36    }
37
38    /// Create a new error object from a printable error message.
39    ///
40    /// If the argument implements std::error::Error, prefer `Error::new`
41    /// instead which preserves the underlying error's cause chain and
42    /// backtrace. If the argument may or may not implement std::error::Error
43    /// now or in the future, use `anyhow!(err)` which handles either way
44    /// correctly.
45    ///
46    /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
47    /// convenient in places where a function is preferable over a macro, such
48    /// as iterator or stream combinators:
49    ///
50    /// ```
51    /// # mod ffi {
52    /// #     pub struct Input;
53    /// #     pub struct Output;
54    /// #     pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
55    /// #         unimplemented!()
56    /// #     }
57    /// # }
58    /// #
59    /// # use ffi::{Input, Output};
60    /// #
61    /// use anyhow::{Error, Result};
62    /// use futures::stream::{Stream, StreamExt, TryStreamExt};
63    ///
64    /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
65    /// where
66    ///     S: Stream<Item = Input>,
67    /// {
68    ///     stream
69    ///         .then(ffi::do_some_work) // returns Result<Output, &str>
70    ///         .map_err(Error::msg)
71    ///         .try_collect()
72    ///         .await
73    /// }
74    /// ```
75    #[cold]
76    #[must_use]
77    pub fn msg<M>(message: M) -> Self
78    where
79        M: Display + Debug + Send + Sync + 'static,
80    {
81        Error::construct_from_adhoc(message, Some(std::backtrace::Backtrace::capture())backtrace!())
82    }
83
84    /// Construct an error object from a type-erased standard library error.
85    ///
86    /// This is mostly useful for interop with other error libraries.
87    ///
88    /// # Example
89    ///
90    /// Here is a skeleton of a library that provides its own error abstraction.
91    /// The pair of `From` impls provide bidirectional support for `?`
92    /// conversion between `Report` and `anyhow::Error`.
93    ///
94    /// ```
95    /// use std::error::Error as StdError;
96    ///
97    /// pub struct Report {/* ... */}
98    ///
99    /// impl<E> From<E> for Report
100    /// where
101    ///     E: Into<anyhow::Error>,
102    ///     Result<(), E>: anyhow::Context<(), E>,
103    /// {
104    ///     fn from(error: E) -> Self {
105    ///         let anyhow_error: anyhow::Error = error.into();
106    ///         let boxed_error: Box<dyn StdError + Send + Sync + 'static> = anyhow_error.into();
107    ///         Report::from_boxed(boxed_error)
108    ///     }
109    /// }
110    ///
111    /// impl From<Report> for anyhow::Error {
112    ///     fn from(report: Report) -> Self {
113    ///         let boxed_error: Box<dyn StdError + Send + Sync + 'static> = report.into_boxed();
114    ///         anyhow::Error::from_boxed(boxed_error)
115    ///     }
116    /// }
117    ///
118    /// impl Report {
119    ///     fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self {
120    ///         todo!()
121    ///     }
122    ///     fn into_boxed(self) -> Box<dyn StdError + Send + Sync + 'static> {
123    ///         todo!()
124    ///     }
125    /// }
126    ///
127    /// // Example usage: can use `?` in both directions.
128    /// fn a() -> anyhow::Result<()> {
129    ///     b()?;
130    ///     Ok(())
131    /// }
132    /// fn b() -> Result<(), Report> {
133    ///     a()?;
134    ///     Ok(())
135    /// }
136    /// ```
137    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
138    #[cold]
139    #[must_use]
140    pub fn from_boxed(boxed_error: Box<dyn StdError + Send + Sync + 'static>) -> Self {
141        let backtrace = match crate::nightly::request_ref_backtrace(&*boxed_error as
            &dyn core::error::Error) {
    Some(_) => None,
    None => Some(std::backtrace::Backtrace::capture()),
}backtrace_if_absent!(&*boxed_error);
142        Error::construct_from_boxed(boxed_error, backtrace)
143    }
144
145    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
146    #[cold]
147    pub(crate) fn construct_from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
148    where
149        E: StdError + Send + Sync + 'static,
150    {
151        let vtable = &ErrorVTable {
152            object_drop: object_drop::<E>,
153            object_ref: object_ref::<E>,
154            object_boxed: object_boxed::<E>,
155            object_reallocate_boxed: object_reallocate_boxed::<E>,
156            object_downcast: object_downcast::<E>,
157            object_drop_rest: object_drop_front::<E>,
158            #[cfg(all(not(error_generic_member_access), feature = "std"))]
159            object_backtrace: no_backtrace,
160        };
161
162        // Safety: passing vtable that operates on the right type E.
163        unsafe { Error::construct(error, vtable, backtrace) }
164    }
165
166    #[cold]
167    pub(crate) fn construct_from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
168    where
169        M: Display + Debug + Send + Sync + 'static,
170    {
171        use crate::wrapper::MessageError;
172        let error: MessageError<M> = MessageError(message);
173        let vtable = &ErrorVTable {
174            object_drop: object_drop::<MessageError<M>>,
175            object_ref: object_ref::<MessageError<M>>,
176            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
177            object_boxed: object_boxed::<MessageError<M>>,
178            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
179            object_reallocate_boxed: object_reallocate_boxed::<MessageError<M>>,
180            object_downcast: object_downcast::<M>,
181            object_drop_rest: object_drop_front::<M>,
182            #[cfg(all(not(error_generic_member_access), feature = "std"))]
183            object_backtrace: no_backtrace,
184        };
185
186        // Safety: MessageError is repr(transparent) so it is okay for the
187        // vtable to allow casting the MessageError<M> to M.
188        unsafe { Error::construct(error, vtable, backtrace) }
189    }
190
191    #[cold]
192    pub(crate) fn construct_from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
193    where
194        M: Display + Send + Sync + 'static,
195    {
196        use crate::wrapper::DisplayError;
197        let error: DisplayError<M> = DisplayError(message);
198        let vtable = &ErrorVTable {
199            object_drop: object_drop::<DisplayError<M>>,
200            object_ref: object_ref::<DisplayError<M>>,
201            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
202            object_boxed: object_boxed::<DisplayError<M>>,
203            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
204            object_reallocate_boxed: object_reallocate_boxed::<DisplayError<M>>,
205            object_downcast: object_downcast::<M>,
206            object_drop_rest: object_drop_front::<M>,
207            #[cfg(all(not(error_generic_member_access), feature = "std"))]
208            object_backtrace: no_backtrace,
209        };
210
211        // Safety: DisplayError is repr(transparent) so it is okay for the
212        // vtable to allow casting the DisplayError<M> to M.
213        unsafe { Error::construct(error, vtable, backtrace) }
214    }
215
216    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
217    #[cold]
218    pub(crate) fn construct_from_context<C, E>(
219        context: C,
220        error: E,
221        backtrace: Option<Backtrace>,
222    ) -> Self
223    where
224        C: Display + Send + Sync + 'static,
225        E: StdError + Send + Sync + 'static,
226    {
227        let error: ContextError<C, E> = ContextError { context, error };
228
229        let vtable = &ErrorVTable {
230            object_drop: object_drop::<ContextError<C, E>>,
231            object_ref: object_ref::<ContextError<C, E>>,
232            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
233            object_boxed: object_boxed::<ContextError<C, E>>,
234            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
235            object_reallocate_boxed: object_reallocate_boxed::<ContextError<C, E>>,
236            object_downcast: context_downcast::<C, E>,
237            object_drop_rest: context_drop_rest::<C, E>,
238            #[cfg(all(not(error_generic_member_access), feature = "std"))]
239            object_backtrace: no_backtrace,
240        };
241
242        // Safety: passing vtable that operates on the right type.
243        unsafe { Error::construct(error, vtable, backtrace) }
244    }
245
246    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
247    #[cold]
248    pub(crate) fn construct_from_boxed(
249        error: Box<dyn StdError + Send + Sync>,
250        backtrace: Option<Backtrace>,
251    ) -> Self {
252        use crate::wrapper::BoxedError;
253        let error = BoxedError(error);
254        let vtable = &ErrorVTable {
255            object_drop: object_drop::<BoxedError>,
256            object_ref: object_ref::<BoxedError>,
257            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
258            object_boxed: object_boxed::<BoxedError>,
259            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
260            object_reallocate_boxed: object_reallocate_boxed::<BoxedError>,
261            object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
262            object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
263            #[cfg(all(not(error_generic_member_access), feature = "std"))]
264            object_backtrace: no_backtrace,
265        };
266
267        // Safety: BoxedError is repr(transparent) so it is okay for the vtable
268        // to allow casting to Box<dyn StdError + Send + Sync>.
269        unsafe { Error::construct(error, vtable, backtrace) }
270    }
271
272    // Takes backtrace as argument rather than capturing it here so that the
273    // user sees one fewer layer of wrapping noise in the backtrace.
274    //
275    // Unsafe because the given vtable must have sensible behavior on the error
276    // value of type E.
277    #[cold]
278    unsafe fn construct<E>(
279        error: E,
280        vtable: &'static ErrorVTable,
281        backtrace: Option<Backtrace>,
282    ) -> Self
283    where
284        E: StdError + Send + Sync + 'static,
285    {
286        let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
287            vtable,
288            backtrace,
289            _object: error,
290        });
291        // Erase the concrete type of E from the compile-time type system. This
292        // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
293        // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
294        // result is a thin pointer. The necessary behavior for manipulating the
295        // underlying ErrorImpl<E> is preserved in the vtable provided by the
296        // caller rather than a builtin fat pointer vtable.
297        let inner = Own::new(inner).cast::<ErrorImpl>();
298        Error { inner }
299    }
300
301    /// Wrap the error value with additional context.
302    ///
303    /// For attaching context to a `Result` as it is propagated, the
304    /// [`Context`][crate::Context] extension trait may be more convenient than
305    /// this function.
306    ///
307    /// The primary reason to use `error.context(...)` instead of
308    /// `result.context(...)` via the `Context` trait would be if the context
309    /// needs to depend on some data held by the underlying error:
310    ///
311    /// ```
312    /// # use std::fmt::{self, Debug, Display};
313    /// #
314    /// # type T = ();
315    /// #
316    /// # impl std::error::Error for ParseError {}
317    /// # impl Debug for ParseError {
318    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
319    /// #         unimplemented!()
320    /// #     }
321    /// # }
322    /// # impl Display for ParseError {
323    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
324    /// #         unimplemented!()
325    /// #     }
326    /// # }
327    /// #
328    /// use anyhow::Result;
329    /// use std::fs::File;
330    /// use std::path::Path;
331    ///
332    /// struct ParseError {
333    ///     line: usize,
334    ///     column: usize,
335    /// }
336    ///
337    /// fn parse_impl(file: File) -> Result<T, ParseError> {
338    ///     # const IGNORE: &str = stringify! {
339    ///     ...
340    ///     # };
341    ///     # unimplemented!()
342    /// }
343    ///
344    /// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
345    ///     let file = File::open(&path)?;
346    ///     parse_impl(file).map_err(|error| {
347    ///         let context = format!(
348    ///             "only the first {} lines of {} are valid",
349    ///             error.line, path.as_ref().display(),
350    ///         );
351    ///         anyhow::Error::new(error).context(context)
352    ///     })
353    /// }
354    /// ```
355    #[cold]
356    #[must_use]
357    pub fn context<C>(self, context: C) -> Self
358    where
359        C: Display + Send + Sync + 'static,
360    {
361        let error: ContextError<C, Error> = ContextError {
362            context,
363            error: self,
364        };
365
366        let vtable = &ErrorVTable {
367            object_drop: object_drop::<ContextError<C, Error>>,
368            object_ref: object_ref::<ContextError<C, Error>>,
369            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
370            object_boxed: object_boxed::<ContextError<C, Error>>,
371            #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
372            object_reallocate_boxed: object_reallocate_boxed::<ContextError<C, Error>>,
373            object_downcast: context_chain_downcast::<C>,
374            object_drop_rest: context_chain_drop_rest::<C>,
375            #[cfg(all(not(error_generic_member_access), feature = "std"))]
376            object_backtrace: context_backtrace::<C>,
377        };
378
379        // As the cause is anyhow::Error, we already have a backtrace for it.
380        let backtrace = None;
381
382        // Safety: passing vtable that operates on the right type.
383        unsafe { Error::construct(error, vtable, backtrace) }
384    }
385
386    /// Get the backtrace for this Error.
387    ///
388    /// In order for the backtrace to be meaningful, one of the two environment
389    /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
390    /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
391    /// expensive to capture in Rust, so we don't necessarily want to be
392    /// capturing them all over the place all the time.
393    ///
394    /// - If you want panics and errors to both have backtraces, set
395    ///   `RUST_BACKTRACE=1`;
396    /// - If you want only errors to have backtraces, set
397    ///   `RUST_LIB_BACKTRACE=1`;
398    /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
399    ///   `RUST_LIB_BACKTRACE=0`.
400    ///
401    /// # Stability
402    ///
403    /// Standard library backtraces are only available when using Rust &ge;
404    /// 1.65. On older compilers, this function is only available if the crate's
405    /// "backtrace" feature is enabled, and will use the `backtrace` crate as
406    /// the underlying backtrace implementation. The return type of this
407    /// function on old compilers is `&(impl Debug + Display)`.
408    ///
409    /// ```toml
410    /// [dependencies]
411    /// anyhow = { version = "1.0", features = ["backtrace"] }
412    /// ```
413    #[cfg(feature = "std")]
414    pub fn backtrace(&self) -> &Backtrace {
415        unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
416    }
417
418    /// An iterator of the chain of source errors contained by this Error.
419    ///
420    /// This iterator will visit every error in the cause chain of this error
421    /// object, beginning with the error that this error object was created
422    /// from.
423    ///
424    /// # Example
425    ///
426    /// ```
427    /// use anyhow::Error;
428    /// use std::io;
429    ///
430    /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
431    ///     for cause in error.chain() {
432    ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
433    ///             return Some(io_error.kind());
434    ///         }
435    ///     }
436    ///     None
437    /// }
438    /// ```
439    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
440    #[cold]
441    pub fn chain(&self) -> Chain {
442        unsafe { ErrorImpl::chain(self.inner.by_ref()) }
443    }
444
445    /// The lowest level cause of this error &mdash; this error's cause's
446    /// cause's cause etc.
447    ///
448    /// The root cause is the last error in the iterator produced by
449    /// [`chain()`][Error::chain].
450    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
451    #[allow(clippy::double_ended_iterator_last)]
452    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
453        self.chain().last().unwrap()
454    }
455
456    /// Returns true if `E` is the type held by this error object.
457    ///
458    /// For errors with context, this method returns true if `E` matches the
459    /// type of the context `C` **or** the type of the error on which the
460    /// context has been attached. For details about the interaction between
461    /// context and downcasting, [see here].
462    ///
463    /// [see here]: crate::Context#effect-on-downcasting
464    pub fn is<E>(&self) -> bool
465    where
466        E: Display + Debug + Send + Sync + 'static,
467    {
468        self.downcast_ref::<E>().is_some()
469    }
470
471    /// Attempt to downcast the error object to a concrete type.
472    pub fn downcast<E>(mut self) -> Result<E, Self>
473    where
474        E: Display + Debug + Send + Sync + 'static,
475    {
476        let target = TypeId::of::<E>();
477        let inner = self.inner.by_mut();
478        unsafe {
479            // Use vtable to find NonNull<()> which points to a value of type E
480            // somewhere inside the data structure.
481            let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
482                Some(addr) => addr.by_mut().extend(),
483                None => return Err(self),
484            };
485
486            // Prepare to read E out of the data structure. We'll drop the rest
487            // of the data structure separately so that E is not dropped.
488            let outer = ManuallyDrop::new(self);
489
490            // Read E from where the vtable found it.
491            let error = addr.cast::<E>().read();
492
493            // Drop rest of the data structure outside of E.
494            (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
495
496            Ok(error)
497        }
498    }
499
500    /// Downcast this error object by reference.
501    ///
502    /// # Example
503    ///
504    /// ```
505    /// # use anyhow::anyhow;
506    /// # use std::fmt::{self, Display};
507    /// # use std::task::Poll;
508    /// #
509    /// # #[derive(Debug)]
510    /// # enum DataStoreError {
511    /// #     Censored(()),
512    /// # }
513    /// #
514    /// # impl Display for DataStoreError {
515    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
516    /// #         unimplemented!()
517    /// #     }
518    /// # }
519    /// #
520    /// # impl std::error::Error for DataStoreError {}
521    /// #
522    /// # const REDACTED_CONTENT: () = ();
523    /// #
524    /// # let error = anyhow!("...");
525    /// # let root_cause = &error;
526    /// #
527    /// # let ret =
528    /// // If the error was caused by redaction, then return a tombstone instead
529    /// // of the content.
530    /// match root_cause.downcast_ref::<DataStoreError>() {
531    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
532    ///     None => Err(error),
533    /// }
534    /// # ;
535    /// ```
536    pub fn downcast_ref<E>(&self) -> Option<&E>
537    where
538        E: Display + Debug + Send + Sync + 'static,
539    {
540        let target = TypeId::of::<E>();
541        unsafe {
542            // Use vtable to find NonNull<()> which points to a value of type E
543            // somewhere inside the data structure.
544            let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
545            Some(addr.cast::<E>().deref())
546        }
547    }
548
549    /// Downcast this error object by mutable reference.
550    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
551    where
552        E: Display + Debug + Send + Sync + 'static,
553    {
554        let target = TypeId::of::<E>();
555        unsafe {
556            // Use vtable to find NonNull<()> which points to a value of type E
557            // somewhere inside the data structure.
558            let addr =
559                (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
560            Some(addr.cast::<E>().deref_mut())
561        }
562    }
563
564    /// Convert to a standard library error trait object.
565    ///
566    /// This is implemented as a cheap pointer cast that does not allocate or
567    /// deallocate memory. Like [`anyhow::Error::from_boxed`], it's useful for
568    /// interop with other error libraries.
569    ///
570    /// The same conversion is also available as
571    /// <code style="display:inline;white-space:normal;">impl From&lt;anyhow::Error&gt;
572    /// for Box&lt;dyn Error + Send + Sync + &apos;static&gt;</code>.
573    ///
574    /// If a backtrace was collected during construction of the `anyhow::Error`,
575    /// that backtrace remains accessible using the standard library `Error`
576    /// trait's provider API, but as a consequence, the resulting boxed error
577    /// can no longer be downcast to its original underlying type.
578    ///
579    /// ```
580    #[cfg_attr(not(error_generic_member_access), doc = "# _ = stringify! {")]
581    /// #![feature(error_generic_member_access)]
582    ///
583    /// use anyhow::anyhow;
584    /// use std::backtrace::Backtrace;
585    /// use thiserror::Error;
586    ///
587    /// #[derive(Error, Debug)]
588    /// #[error("...")]
589    /// struct MyError;
590    ///
591    /// let anyhow_error = anyhow!(MyError);
592    /// println!("{}", anyhow_error.backtrace());  // has Backtrace
593    /// assert!(anyhow_error.downcast_ref::<MyError>().is_some());  // can downcast
594    ///
595    /// let boxed_dyn_error = anyhow_error.into_boxed_dyn_error();
596    /// assert!(std::error::request_ref::<Backtrace>(&*boxed_dyn_error).is_some());  // has Backtrace
597    /// assert!(boxed_dyn_error.downcast_ref::<MyError>().is_none());  // can no longer downcast
598    #[cfg_attr(not(error_generic_member_access), doc = "# };")]
599    /// ```
600    ///
601    /// [`anyhow::Error::from_boxed`]: Self::from_boxed
602    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
603    #[must_use]
604    pub fn into_boxed_dyn_error(self) -> Box<dyn StdError + Send + Sync + 'static> {
605        let outer = ManuallyDrop::new(self);
606        unsafe {
607            // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
608            // the right original type E.
609            (vtable(outer.inner.ptr).object_boxed)(outer.inner)
610        }
611    }
612
613    /// Convert to a standard library error trait object.
614    ///
615    /// Unlike `self.into_boxed_dyn_error()`, this method relocates the
616    /// underlying error into a new allocation in order to make it downcastable
617    /// to `&E` or `Box<E>` for its original underlying error type. Any
618    /// backtrace collected during construction of the `anyhow::Error` is
619    /// discarded.
620    ///
621    /// ```
622    #[cfg_attr(not(error_generic_member_access), doc = "# _ = stringify!{")]
623    /// #![feature(error_generic_member_access)]
624    ///
625    /// use anyhow::anyhow;
626    /// use std::backtrace::Backtrace;
627    /// use thiserror::Error;
628    ///
629    /// #[derive(Error, Debug)]
630    /// #[error("...")]
631    /// struct MyError;
632    ///
633    /// let anyhow_error = anyhow!(MyError);
634    /// println!("{}", anyhow_error.backtrace());  // has Backtrace
635    /// assert!(anyhow_error.downcast_ref::<MyError>().is_some());  // can downcast
636    ///
637    /// let boxed_dyn_error = anyhow_error.reallocate_into_boxed_dyn_error_without_backtrace();
638    /// assert!(std::error::request_ref::<Backtrace>(&*boxed_dyn_error).is_none());  // Backtrace lost
639    /// assert!(boxed_dyn_error.downcast_ref::<MyError>().is_some());  // can downcast to &MyError
640    /// assert!(boxed_dyn_error.downcast::<MyError>().is_ok());  // can downcast to Box<MyError>
641    #[cfg_attr(not(error_generic_member_access), doc = "# };")]
642    /// ```
643    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
644    #[must_use]
645    pub fn reallocate_into_boxed_dyn_error_without_backtrace(
646        self,
647    ) -> Box<dyn StdError + Send + Sync + 'static> {
648        let outer = ManuallyDrop::new(self);
649        unsafe {
650            // Use vtable to attach E's native StdError vtable for the right
651            // original type E.
652            (vtable(outer.inner.ptr).object_reallocate_boxed)(outer.inner)
653        }
654    }
655
656    #[cfg(error_generic_member_access)]
657    pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
658        unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
659    }
660
661    // Called by thiserror when you have `#[source] anyhow::Error`. This provide
662    // implementation includes the anyhow::Error's Backtrace if any, unlike
663    // deref'ing to dyn Error where the provide implementation would include
664    // only the original error's Backtrace from before it got wrapped into an
665    // anyhow::Error.
666    #[cfg(error_generic_member_access)]
667    #[doc(hidden)]
668    pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
669        Self::provide(self, request);
670    }
671}
672
673#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
674impl<E> From<E> for Error
675where
676    E: StdError + Send + Sync + 'static,
677{
678    #[cold]
679    fn from(error: E) -> Self {
680        let backtrace = match crate::nightly::request_ref_backtrace(&error as &dyn core::error::Error)
    {
    Some(_) => None,
    None => Some(std::backtrace::Backtrace::capture()),
}backtrace_if_absent!(&error);
681        Error::construct_from_std(error, backtrace)
682    }
683}
684
685#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
686impl Deref for Error {
687    type Target = dyn StdError + Send + Sync + 'static;
688
689    fn deref(&self) -> &Self::Target {
690        unsafe { ErrorImpl::error(self.inner.by_ref()) }
691    }
692}
693
694#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
695impl DerefMut for Error {
696    fn deref_mut(&mut self) -> &mut Self::Target {
697        unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
698    }
699}
700
701impl Display for Error {
702    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
703        unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
704    }
705}
706
707impl Debug for Error {
708    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
709        unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
710    }
711}
712
713impl Drop for Error {
714    fn drop(&mut self) {
715        unsafe {
716            // Invoke the vtable's drop behavior.
717            (vtable(self.inner.ptr).object_drop)(self.inner);
718        }
719    }
720}
721
722struct ErrorVTable {
723    object_drop: unsafe fn(Own<ErrorImpl>),
724    object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
725    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
726    object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
727    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
728    object_reallocate_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
729    object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
730    object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
731    #[cfg(all(not(error_generic_member_access), feature = "std"))]
732    object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
733}
734
735// Safety: requires layout of *e to match ErrorImpl<E>.
736unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
737    // Cast back to ErrorImpl<E> so that the allocator receives the correct
738    // Layout to deallocate the Box's memory.
739    let unerased_own = e.cast::<ErrorImpl<E>>();
740    drop(unsafe { unerased_own.boxed() });
741}
742
743// Safety: requires layout of *e to match ErrorImpl<E>.
744unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
745    // Drop the fields of ErrorImpl other than E as well as the Box allocation,
746    // without dropping E itself. This is used by downcast after doing a
747    // ptr::read to take ownership of the E.
748    let _ = target;
749    let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
750    drop(unsafe { unerased_own.boxed() });
751}
752
753// Safety: requires layout of *e to match ErrorImpl<E>.
754unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
755where
756    E: StdError + Send + Sync + 'static,
757{
758    // Attach E's native StdError vtable onto a pointer to self._object.
759    let unerased_ref = e.cast::<ErrorImpl<E>>();
760    Ref::from_raw(unsafe {
761        NonNull::new_unchecked(&raw const (*unerased_ref.as_ptr())._objectptr::addr_of!((*unerased_ref.as_ptr())._object).cast_mut())
762    })
763}
764
765// Safety: requires layout of *e to match ErrorImpl<E>.
766#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
767unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
768where
769    E: StdError + Send + Sync + 'static,
770{
771    // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
772    let unerased_own = e.cast::<ErrorImpl<E>>();
773    unsafe { unerased_own.boxed() }
774}
775
776// Safety: requires layout of *e to match ErrorImpl<E>.
777#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
778unsafe fn object_reallocate_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
779where
780    E: StdError + Send + Sync + 'static,
781{
782    // Attach E's native StdError vtable.
783    let unerased_own = e.cast::<ErrorImpl<E>>();
784    Box::new(unsafe { unerased_own.boxed() }._object)
785}
786
787// Safety: requires layout of *e to match ErrorImpl<E>.
788unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
789where
790    E: 'static,
791{
792    if TypeId::of::<E>() == target {
793        // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
794        // pointer to its E field.
795        let unerased_ref = e.cast::<ErrorImpl<E>>();
796        Some(
797            Ref::from_raw(unsafe {
798                NonNull::new_unchecked(&raw const (*unerased_ref.as_ptr())._objectptr::addr_of!((*unerased_ref.as_ptr())._object).cast_mut())
799            })
800            .cast::<()>(),
801        )
802    } else {
803        None
804    }
805}
806
807#[cfg(all(not(error_generic_member_access), feature = "std"))]
808fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
809    let _ = e;
810    None
811}
812
813// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
814#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
815unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
816where
817    C: 'static,
818    E: 'static,
819{
820    if TypeId::of::<C>() == target {
821        let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
822        let unerased = unsafe { unerased_ref.deref() };
823        Some(Ref::new(&unerased._object.context).cast::<()>())
824    } else if TypeId::of::<E>() == target {
825        let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
826        let unerased = unsafe { unerased_ref.deref() };
827        Some(Ref::new(&unerased._object.error).cast::<()>())
828    } else {
829        None
830    }
831}
832
833// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
834#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
835unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
836where
837    C: 'static,
838    E: 'static,
839{
840    // Called after downcasting by value to either the C or the E and doing a
841    // ptr::read to take ownership of that value.
842    if TypeId::of::<C>() == target {
843        let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
844        drop(unsafe { unerased_own.boxed() });
845    } else {
846        let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
847        drop(unsafe { unerased_own.boxed() });
848    }
849}
850
851// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
852unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
853where
854    C: 'static,
855{
856    let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
857    let unerased = unsafe { unerased_ref.deref() };
858    if TypeId::of::<C>() == target {
859        Some(Ref::new(&unerased._object.context).cast::<()>())
860    } else {
861        // Recurse down the context chain per the inner error's vtable.
862        let source = &unerased._object.error;
863        unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
864    }
865}
866
867// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
868unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
869where
870    C: 'static,
871{
872    // Called after downcasting by value to either the C or one of the causes
873    // and doing a ptr::read to take ownership of that value.
874    if TypeId::of::<C>() == target {
875        let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
876        // Drop the entire rest of the data structure rooted in the next Error.
877        drop(unsafe { unerased_own.boxed() });
878    } else {
879        let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
880        let unerased = unsafe { unerased_own.boxed() };
881        // Read the Own<ErrorImpl> from the next error.
882        let inner = unerased._object.error.inner;
883        drop(unerased);
884        let vtable = unsafe { vtable(inner.ptr) };
885        // Recursively drop the next error using the same target typeid.
886        unsafe { (vtable.object_drop_rest)(inner, target) };
887    }
888}
889
890// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
891#[cfg(all(not(error_generic_member_access), feature = "std"))]
892#[allow(clippy::unnecessary_wraps)]
893unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
894where
895    C: 'static,
896{
897    let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
898    let unerased = unsafe { unerased_ref.deref() };
899    let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) };
900    Some(backtrace)
901}
902
903// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
904// of raw pointers and `NonNull`.
905// repr C to ensure that E remains in the final position.
906#[repr(C)]
907pub(crate) struct ErrorImpl<E = ()> {
908    vtable: &'static ErrorVTable,
909    backtrace: Option<Backtrace>,
910    // NOTE: Don't use directly. Use only through vtable. Erased type may have
911    // different alignment.
912    _object: E,
913}
914
915// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
916// avoids converting `p` into a reference.
917unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
918    // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
919    unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
920}
921
922// repr C to ensure that ContextError<C, E> has the same layout as
923// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
924#[repr(C)]
925pub(crate) struct ContextError<C, E> {
926    pub context: C,
927    pub error: E,
928}
929
930impl<E> ErrorImpl<E> {
931    fn erase(&self) -> Ref<ErrorImpl> {
932        // Erase the concrete type of E but preserve the vtable in self.vtable
933        // for manipulating the resulting thin pointer. This is analogous to an
934        // unsize coercion.
935        Ref::new(self).cast::<ErrorImpl>()
936    }
937}
938
939impl ErrorImpl {
940    pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
941        // Use vtable to attach E's native StdError vtable for the right
942        // original type E.
943        unsafe { (vtable(this.ptr).object_ref)(this).deref() }
944    }
945
946    #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
947    pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
948        // Use vtable to attach E's native StdError vtable for the right
949        // original type E.
950        unsafe {
951            (vtable(this.ptr).object_ref)(this.by_ref())
952                .by_mut()
953                .deref_mut()
954        }
955    }
956
957    #[cfg(feature = "std")]
958    pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
959        // This unwrap can only panic if the underlying error's backtrace method
960        // is nondeterministic, which would only happen in maliciously
961        // constructed code.
962        unsafe { this.deref() }
963            .backtrace
964            .as_ref()
965            .or_else(|| {
966                #[cfg(error_generic_member_access)]
967                return nightly::request_ref_backtrace(unsafe { Self::error(this) });
968                #[cfg(not(error_generic_member_access))]
969                return unsafe { (vtable(this.ptr).object_backtrace)(this) };
970            })
971            .expect("backtrace capture failed")
972    }
973
974    #[cfg(error_generic_member_access)]
975    unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
976        if let Some(backtrace) = unsafe { &this.deref().backtrace } {
977            nightly::provide_ref_backtrace(request, backtrace);
978        }
979        nightly::provide(unsafe { Self::error(this) }, request);
980    }
981
982    #[cold]
983    pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
984        Chain::new(unsafe { Self::error(this) })
985    }
986}
987
988impl<E> StdError for ErrorImpl<E>
989where
990    E: StdError,
991{
992    fn source(&self) -> Option<&(dyn StdError + 'static)> {
993        unsafe { ErrorImpl::error(self.erase()).source() }
994    }
995
996    #[cfg(error_generic_member_access)]
997    fn provide<'a>(&'a self, request: &mut Request<'a>) {
998        unsafe { ErrorImpl::provide(self.erase(), request) }
999    }
1000}
1001
1002impl<E> Debug for ErrorImpl<E>
1003where
1004    E: Debug,
1005{
1006    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1007        unsafe { ErrorImpl::debug(self.erase(), formatter) }
1008    }
1009}
1010
1011impl<E> Display for ErrorImpl<E>
1012where
1013    E: Display,
1014{
1015    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1016        unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
1017    }
1018}
1019
1020#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1021impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
1022    #[cold]
1023    fn from(error: Error) -> Self {
1024        error.into_boxed_dyn_error()
1025    }
1026}
1027
1028#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1029impl From<Error> for Box<dyn StdError + Send + 'static> {
1030    #[cold]
1031    fn from(error: Error) -> Self {
1032        error.into_boxed_dyn_error()
1033    }
1034}
1035
1036#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1037impl From<Error> for Box<dyn StdError + 'static> {
1038    #[cold]
1039    fn from(error: Error) -> Self {
1040        error.into_boxed_dyn_error()
1041    }
1042}
1043
1044#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1045impl AsRef<dyn StdError + Send + Sync> for Error {
1046    fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
1047        &**self
1048    }
1049}
1050
1051#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1052impl AsRef<dyn StdError> for Error {
1053    fn as_ref(&self) -> &(dyn StdError + 'static) {
1054        &**self
1055    }
1056}
1057
1058impl UnwindSafe for Error {}
1059impl RefUnwindSafe for Error {}