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