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 = 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, 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 = 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(
159 not(error_generic_member_access),
160 any(std_backtrace, feature = "backtrace")
161 ))]
162 object_backtrace: no_backtrace,
163 };
164
165 // Safety: passing vtable that operates on the right type E.
166 unsafe { Error::construct(error, vtable, backtrace) }
167 }
168
169 #[cold]
170 pub(crate) fn construct_from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
171 where
172 M: Display + Debug + Send + Sync + 'static,
173 {
174 use crate::wrapper::MessageError;
175 let error: MessageError<M> = MessageError(message);
176 let vtable = &ErrorVTable {
177 object_drop: object_drop::<MessageError<M>>,
178 object_ref: object_ref::<MessageError<M>>,
179 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
180 object_boxed: object_boxed::<MessageError<M>>,
181 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
182 object_reallocate_boxed: object_reallocate_boxed::<MessageError<M>>,
183 object_downcast: object_downcast::<M>,
184 object_drop_rest: object_drop_front::<M>,
185 #[cfg(all(
186 not(error_generic_member_access),
187 any(std_backtrace, feature = "backtrace")
188 ))]
189 object_backtrace: no_backtrace,
190 };
191
192 // Safety: MessageError is repr(transparent) so it is okay for the
193 // vtable to allow casting the MessageError<M> to M.
194 unsafe { Error::construct(error, vtable, backtrace) }
195 }
196
197 #[cold]
198 pub(crate) fn construct_from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
199 where
200 M: Display + Send + Sync + 'static,
201 {
202 use crate::wrapper::DisplayError;
203 let error: DisplayError<M> = DisplayError(message);
204 let vtable = &ErrorVTable {
205 object_drop: object_drop::<DisplayError<M>>,
206 object_ref: object_ref::<DisplayError<M>>,
207 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
208 object_boxed: object_boxed::<DisplayError<M>>,
209 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
210 object_reallocate_boxed: object_reallocate_boxed::<DisplayError<M>>,
211 object_downcast: object_downcast::<M>,
212 object_drop_rest: object_drop_front::<M>,
213 #[cfg(all(
214 not(error_generic_member_access),
215 any(std_backtrace, feature = "backtrace")
216 ))]
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 pub(crate) fn construct_from_context<C, E>(
228 context: C,
229 error: E,
230 backtrace: Option<Backtrace>,
231 ) -> Self
232 where
233 C: Display + Send + Sync + 'static,
234 E: StdError + Send + Sync + 'static,
235 {
236 let error: ContextError<C, E> = ContextError { context, error };
237
238 let vtable = &ErrorVTable {
239 object_drop: object_drop::<ContextError<C, E>>,
240 object_ref: object_ref::<ContextError<C, E>>,
241 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
242 object_boxed: object_boxed::<ContextError<C, E>>,
243 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
244 object_reallocate_boxed: object_reallocate_boxed::<ContextError<C, E>>,
245 object_downcast: context_downcast::<C, E>,
246 object_drop_rest: context_drop_rest::<C, E>,
247 #[cfg(all(
248 not(error_generic_member_access),
249 any(std_backtrace, feature = "backtrace")
250 ))]
251 object_backtrace: no_backtrace,
252 };
253
254 // Safety: passing vtable that operates on the right type.
255 unsafe { Error::construct(error, vtable, backtrace) }
256 }
257
258 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
259 #[cold]
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 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
270 object_boxed: object_boxed::<BoxedError>,
271 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
272 object_reallocate_boxed: object_reallocate_boxed::<BoxedError>,
273 object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
274 object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
275 #[cfg(all(
276 not(error_generic_member_access),
277 any(std_backtrace, feature = "backtrace")
278 ))]
279 object_backtrace: no_backtrace,
280 };
281
282 // Safety: BoxedError is repr(transparent) so it is okay for the vtable
283 // to allow casting to Box<dyn StdError + Send + Sync>.
284 unsafe { Error::construct(error, vtable, backtrace) }
285 }
286
287 // Takes backtrace as argument rather than capturing it here so that the
288 // user sees one fewer layer of wrapping noise in the backtrace.
289 //
290 // Unsafe because the given vtable must have sensible behavior on the error
291 // value of type E.
292 #[cold]
293 unsafe fn construct<E>(
294 error: E,
295 vtable: &'static ErrorVTable,
296 backtrace: Option<Backtrace>,
297 ) -> Self
298 where
299 E: StdError + Send + Sync + 'static,
300 {
301 let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
302 vtable,
303 backtrace,
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 pub fn context<C>(self, context: C) -> Self
373 where
374 C: Display + Send + Sync + 'static,
375 {
376 let error: ContextError<C, Error> = ContextError {
377 context,
378 error: self,
379 };
380
381 let vtable = &ErrorVTable {
382 object_drop: object_drop::<ContextError<C, Error>>,
383 object_ref: object_ref::<ContextError<C, Error>>,
384 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
385 object_boxed: object_boxed::<ContextError<C, Error>>,
386 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
387 object_reallocate_boxed: object_reallocate_boxed::<ContextError<C, Error>>,
388 object_downcast: context_chain_downcast::<C>,
389 object_drop_rest: context_chain_drop_rest::<C>,
390 #[cfg(all(
391 not(error_generic_member_access),
392 any(std_backtrace, feature = "backtrace")
393 ))]
394 object_backtrace: context_backtrace::<C>,
395 };
396
397 // As the cause is anyhow::Error, we already have a backtrace for it.
398 let backtrace = None;
399
400 // Safety: passing vtable that operates on the right type.
401 unsafe { Error::construct(error, vtable, backtrace) }
402 }
403
404 /// Get the backtrace for this Error.
405 ///
406 /// In order for the backtrace to be meaningful, one of the two environment
407 /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
408 /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
409 /// expensive to capture in Rust, so we don't necessarily want to be
410 /// capturing them all over the place all the time.
411 ///
412 /// - If you want panics and errors to both have backtraces, set
413 /// `RUST_BACKTRACE=1`;
414 /// - If you want only errors to have backtraces, set
415 /// `RUST_LIB_BACKTRACE=1`;
416 /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
417 /// `RUST_LIB_BACKTRACE=0`.
418 ///
419 /// # Stability
420 ///
421 /// Standard library backtraces are only available when using Rust ≥
422 /// 1.65. On older compilers, this function is only available if the crate's
423 /// "backtrace" feature is enabled, and will use the `backtrace` crate as
424 /// the underlying backtrace implementation. The return type of this
425 /// function on old compilers is `&(impl Debug + Display)`.
426 ///
427 /// ```toml
428 /// [dependencies]
429 /// anyhow = { version = "1.0", features = ["backtrace"] }
430 /// ```
431 #[cfg(any(std_backtrace, feature = "backtrace"))]
432 pub fn backtrace(&self) -> &impl_backtrace!() {
433 unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
434 }
435
436 /// An iterator of the chain of source errors contained by this Error.
437 ///
438 /// This iterator will visit every error in the cause chain of this error
439 /// object, beginning with the error that this error object was created
440 /// from.
441 ///
442 /// # Example
443 ///
444 /// ```
445 /// use anyhow::Error;
446 /// use std::io;
447 ///
448 /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
449 /// for cause in error.chain() {
450 /// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
451 /// return Some(io_error.kind());
452 /// }
453 /// }
454 /// None
455 /// }
456 /// ```
457 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
458 #[cold]
459 pub fn chain(&self) -> Chain {
460 unsafe { ErrorImpl::chain(self.inner.by_ref()) }
461 }
462
463 /// The lowest level cause of this error — this error's cause's
464 /// cause's cause etc.
465 ///
466 /// The root cause is the last error in the iterator produced by
467 /// [`chain()`][Error::chain].
468 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
469 #[allow(clippy::double_ended_iterator_last)]
470 pub fn root_cause(&self) -> &(dyn StdError + 'static) {
471 self.chain().last().unwrap()
472 }
473
474 /// Returns true if `E` is the type held by this error object.
475 ///
476 /// For errors with context, this method returns true if `E` matches the
477 /// type of the context `C` **or** the type of the error on which the
478 /// context has been attached. For details about the interaction between
479 /// context and downcasting, [see here].
480 ///
481 /// [see here]: crate::Context#effect-on-downcasting
482 pub fn is<E>(&self) -> bool
483 where
484 E: Display + Debug + Send + Sync + 'static,
485 {
486 self.downcast_ref::<E>().is_some()
487 }
488
489 /// Attempt to downcast the error object to a concrete type.
490 pub fn downcast<E>(mut self) -> Result<E, Self>
491 where
492 E: Display + Debug + Send + Sync + 'static,
493 {
494 let target = TypeId::of::<E>();
495 let inner = self.inner.by_mut();
496 unsafe {
497 // Use vtable to find NonNull<()> which points to a value of type E
498 // somewhere inside the data structure.
499 let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
500 Some(addr) => addr.by_mut().extend(),
501 None => return Err(self),
502 };
503
504 // Prepare to read E out of the data structure. We'll drop the rest
505 // of the data structure separately so that E is not dropped.
506 let outer = ManuallyDrop::new(self);
507
508 // Read E from where the vtable found it.
509 let error = addr.cast::<E>().read();
510
511 // Drop rest of the data structure outside of E.
512 (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
513
514 Ok(error)
515 }
516 }
517
518 /// Downcast this error object by reference.
519 ///
520 /// # Example
521 ///
522 /// ```
523 /// # use anyhow::anyhow;
524 /// # use std::fmt::{self, Display};
525 /// # use std::task::Poll;
526 /// #
527 /// # #[derive(Debug)]
528 /// # enum DataStoreError {
529 /// # Censored(()),
530 /// # }
531 /// #
532 /// # impl Display for DataStoreError {
533 /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
534 /// # unimplemented!()
535 /// # }
536 /// # }
537 /// #
538 /// # impl std::error::Error for DataStoreError {}
539 /// #
540 /// # const REDACTED_CONTENT: () = ();
541 /// #
542 /// # let error = anyhow!("...");
543 /// # let root_cause = &error;
544 /// #
545 /// # let ret =
546 /// // If the error was caused by redaction, then return a tombstone instead
547 /// // of the content.
548 /// match root_cause.downcast_ref::<DataStoreError>() {
549 /// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
550 /// None => Err(error),
551 /// }
552 /// # ;
553 /// ```
554 pub fn downcast_ref<E>(&self) -> Option<&E>
555 where
556 E: Display + Debug + Send + Sync + 'static,
557 {
558 let target = TypeId::of::<E>();
559 unsafe {
560 // Use vtable to find NonNull<()> which points to a value of type E
561 // somewhere inside the data structure.
562 let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
563 Some(addr.cast::<E>().deref())
564 }
565 }
566
567 /// Downcast this error object by mutable reference.
568 pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
569 where
570 E: Display + Debug + Send + Sync + 'static,
571 {
572 let target = TypeId::of::<E>();
573 unsafe {
574 // Use vtable to find NonNull<()> which points to a value of type E
575 // somewhere inside the data structure.
576 let addr =
577 (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
578 Some(addr.cast::<E>().deref_mut())
579 }
580 }
581
582 /// Convert to a standard library error trait object.
583 ///
584 /// This is implemented as a cheap pointer cast that does not allocate or
585 /// deallocate memory. Like [`anyhow::Error::from_boxed`], it's useful for
586 /// interop with other error libraries.
587 ///
588 /// The same conversion is also available as
589 /// <code style="display:inline;white-space:normal;">impl From<anyhow::Error>
590 /// for Box<dyn Error + Send + Sync + 'static></code>.
591 ///
592 /// If a backtrace was collected during construction of the `anyhow::Error`,
593 /// that backtrace remains accessible using the standard library `Error`
594 /// trait's provider API, but as a consequence, the resulting boxed error
595 /// can no longer be downcast to its original underlying type.
596 ///
597 /// ```
598 #[cfg_attr(not(error_generic_member_access), doc = "# _ = stringify! {")]
599 /// #![feature(error_generic_member_access)]
600 ///
601 /// use anyhow::anyhow;
602 /// use std::backtrace::Backtrace;
603 /// use thiserror::Error;
604 ///
605 /// #[derive(Error, Debug)]
606 /// #[error("...")]
607 /// struct MyError;
608 ///
609 /// let anyhow_error = anyhow!(MyError);
610 /// println!("{}", anyhow_error.backtrace()); // has Backtrace
611 /// assert!(anyhow_error.downcast_ref::<MyError>().is_some()); // can downcast
612 ///
613 /// let boxed_dyn_error = anyhow_error.into_boxed_dyn_error();
614 /// assert!(std::error::request_ref::<Backtrace>(&*boxed_dyn_error).is_some()); // has Backtrace
615 /// assert!(boxed_dyn_error.downcast_ref::<MyError>().is_none()); // can no longer downcast
616 #[cfg_attr(not(error_generic_member_access), doc = "# };")]
617 /// ```
618 ///
619 /// [`anyhow::Error::from_boxed`]: Self::from_boxed
620 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
621 #[must_use]
622 pub fn into_boxed_dyn_error(self) -> Box<dyn StdError + Send + Sync + 'static> {
623 let outer = ManuallyDrop::new(self);
624 unsafe {
625 // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
626 // the right original type E.
627 (vtable(outer.inner.ptr).object_boxed)(outer.inner)
628 }
629 }
630
631 /// Convert to a standard library error trait object.
632 ///
633 /// Unlike `self.into_boxed_dyn_error()`, this method relocates the
634 /// underlying error into a new allocation in order to make it downcastable
635 /// to `&E` or `Box<E>` for its original underlying error type. Any
636 /// backtrace collected during construction of the `anyhow::Error` is
637 /// discarded.
638 ///
639 /// ```
640 #[cfg_attr(not(error_generic_member_access), doc = "# _ = stringify!{")]
641 /// #![feature(error_generic_member_access)]
642 ///
643 /// use anyhow::anyhow;
644 /// use std::backtrace::Backtrace;
645 /// use thiserror::Error;
646 ///
647 /// #[derive(Error, Debug)]
648 /// #[error("...")]
649 /// struct MyError;
650 ///
651 /// let anyhow_error = anyhow!(MyError);
652 /// println!("{}", anyhow_error.backtrace()); // has Backtrace
653 /// assert!(anyhow_error.downcast_ref::<MyError>().is_some()); // can downcast
654 ///
655 /// let boxed_dyn_error = anyhow_error.reallocate_into_boxed_dyn_error_without_backtrace();
656 /// assert!(std::error::request_ref::<Backtrace>(&*boxed_dyn_error).is_none()); // Backtrace lost
657 /// assert!(boxed_dyn_error.downcast_ref::<MyError>().is_some()); // can downcast to &MyError
658 /// assert!(boxed_dyn_error.downcast::<MyError>().is_ok()); // can downcast to Box<MyError>
659 #[cfg_attr(not(error_generic_member_access), doc = "# };")]
660 /// ```
661 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
662 #[must_use]
663 pub fn reallocate_into_boxed_dyn_error_without_backtrace(
664 self,
665 ) -> Box<dyn StdError + Send + Sync + 'static> {
666 let outer = ManuallyDrop::new(self);
667 unsafe {
668 // Use vtable to attach E's native StdError vtable for the right
669 // original type E.
670 (vtable(outer.inner.ptr).object_reallocate_boxed)(outer.inner)
671 }
672 }
673
674 #[cfg(error_generic_member_access)]
675 pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
676 unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
677 }
678
679 // Called by thiserror when you have `#[source] anyhow::Error`. This provide
680 // implementation includes the anyhow::Error's Backtrace if any, unlike
681 // deref'ing to dyn Error where the provide implementation would include
682 // only the original error's Backtrace from before it got wrapped into an
683 // anyhow::Error.
684 #[cfg(error_generic_member_access)]
685 #[doc(hidden)]
686 pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
687 Self::provide(self, request);
688 }
689}
690
691#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
692impl<E> From<E> for Error
693where
694 E: StdError + Send + Sync + 'static,
695{
696 #[cold]
697 fn from(error: E) -> Self {
698 let backtrace = 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 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
744 object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
745 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
746 object_reallocate_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
747 object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
748 object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
749 #[cfg(all(
750 not(error_generic_member_access),
751 any(std_backtrace, feature = "backtrace")
752 ))]
753 object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
754}
755
756// Safety: requires layout of *e to match ErrorImpl<E>.
757unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
758 // Cast back to ErrorImpl<E> so that the allocator receives the correct
759 // Layout to deallocate the Box's memory.
760 let unerased_own = e.cast::<ErrorImpl<E>>();
761 drop(unsafe { unerased_own.boxed() });
762}
763
764// Safety: requires layout of *e to match ErrorImpl<E>.
765unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
766 // Drop the fields of ErrorImpl other than E as well as the Box allocation,
767 // without dropping E itself. This is used by downcast after doing a
768 // ptr::read to take ownership of the E.
769 let _ = target;
770 let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
771 drop(unsafe { unerased_own.boxed() });
772}
773
774// Safety: requires layout of *e to match ErrorImpl<E>.
775unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
776where
777 E: StdError + Send + Sync + 'static,
778{
779 // Attach E's native StdError vtable onto a pointer to self._object.
780 let unerased_ref = e.cast::<ErrorImpl<E>>();
781 Ref::from_raw(unsafe {
782 NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object).cast_mut())
783 })
784}
785
786// Safety: requires layout of *e to match ErrorImpl<E>.
787#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
788unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
789where
790 E: StdError + Send + Sync + 'static,
791{
792 // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
793 let unerased_own = e.cast::<ErrorImpl<E>>();
794 unsafe { unerased_own.boxed() }
795}
796
797// Safety: requires layout of *e to match ErrorImpl<E>.
798#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
799unsafe fn object_reallocate_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
800where
801 E: StdError + Send + Sync + 'static,
802{
803 // Attach E's native StdError vtable.
804 let unerased_own = e.cast::<ErrorImpl<E>>();
805 Box::new(unsafe { unerased_own.boxed() }._object)
806}
807
808// Safety: requires layout of *e to match ErrorImpl<E>.
809unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
810where
811 E: 'static,
812{
813 if TypeId::of::<E>() == target {
814 // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
815 // pointer to its E field.
816 let unerased_ref = e.cast::<ErrorImpl<E>>();
817 Some(
818 Ref::from_raw(unsafe {
819 NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object).cast_mut())
820 })
821 .cast::<()>(),
822 )
823 } else {
824 None
825 }
826}
827
828#[cfg(all(
829 not(error_generic_member_access),
830 any(std_backtrace, feature = "backtrace")
831))]
832fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
833 let _ = e;
834 None
835}
836
837// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
838#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
839unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
840where
841 C: 'static,
842 E: 'static,
843{
844 if TypeId::of::<C>() == target {
845 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
846 let unerased = unsafe { unerased_ref.deref() };
847 Some(Ref::new(&unerased._object.context).cast::<()>())
848 } else if TypeId::of::<E>() == target {
849 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
850 let unerased = unsafe { unerased_ref.deref() };
851 Some(Ref::new(&unerased._object.error).cast::<()>())
852 } else {
853 None
854 }
855}
856
857// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
858#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
859unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
860where
861 C: 'static,
862 E: 'static,
863{
864 // Called after downcasting by value to either the C or the E and doing a
865 // ptr::read to take ownership of that value.
866 if TypeId::of::<C>() == target {
867 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
868 drop(unsafe { unerased_own.boxed() });
869 } else {
870 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
871 drop(unsafe { unerased_own.boxed() });
872 }
873}
874
875// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
876unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
877where
878 C: 'static,
879{
880 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
881 let unerased = unsafe { unerased_ref.deref() };
882 if TypeId::of::<C>() == target {
883 Some(Ref::new(&unerased._object.context).cast::<()>())
884 } else {
885 // Recurse down the context chain per the inner error's vtable.
886 let source = &unerased._object.error;
887 unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
888 }
889}
890
891// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
892unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
893where
894 C: 'static,
895{
896 // Called after downcasting by value to either the C or one of the causes
897 // and doing a ptr::read to take ownership of that value.
898 if TypeId::of::<C>() == target {
899 let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
900 // Drop the entire rest of the data structure rooted in the next Error.
901 drop(unsafe { unerased_own.boxed() });
902 } else {
903 let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
904 let unerased = unsafe { unerased_own.boxed() };
905 // Read the Own<ErrorImpl> from the next error.
906 let inner = unerased._object.error.inner;
907 drop(unerased);
908 let vtable = unsafe { vtable(inner.ptr) };
909 // Recursively drop the next error using the same target typeid.
910 unsafe { (vtable.object_drop_rest)(inner, target) };
911 }
912}
913
914// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
915#[cfg(all(
916 not(error_generic_member_access),
917 any(std_backtrace, feature = "backtrace")
918))]
919#[allow(clippy::unnecessary_wraps)]
920unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
921where
922 C: 'static,
923{
924 let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
925 let unerased = unsafe { unerased_ref.deref() };
926 let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) };
927 Some(backtrace)
928}
929
930// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
931// of raw pointers and `NonNull`.
932// repr C to ensure that E remains in the final position.
933#[repr(C)]
934pub(crate) struct ErrorImpl<E = ()> {
935 vtable: &'static ErrorVTable,
936 backtrace: Option<Backtrace>,
937 // NOTE: Don't use directly. Use only through vtable. Erased type may have
938 // different alignment.
939 _object: E,
940}
941
942// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
943// avoids converting `p` into a reference.
944unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
945 // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
946 unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
947}
948
949// repr C to ensure that ContextError<C, E> has the same layout as
950// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
951#[repr(C)]
952pub(crate) struct ContextError<C, E> {
953 pub context: C,
954 pub error: E,
955}
956
957impl<E> ErrorImpl<E> {
958 fn erase(&self) -> Ref<ErrorImpl> {
959 // Erase the concrete type of E but preserve the vtable in self.vtable
960 // for manipulating the resulting thin pointer. This is analogous to an
961 // unsize coercion.
962 Ref::new(self).cast::<ErrorImpl>()
963 }
964}
965
966impl ErrorImpl {
967 pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
968 // Use vtable to attach E's native StdError vtable for the right
969 // original type E.
970 unsafe { (vtable(this.ptr).object_ref)(this).deref() }
971 }
972
973 #[cfg(any(feature = "std", not(anyhow_no_core_error)))]
974 pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
975 // Use vtable to attach E's native StdError vtable for the right
976 // original type E.
977 unsafe {
978 (vtable(this.ptr).object_ref)(this.by_ref())
979 .by_mut()
980 .deref_mut()
981 }
982 }
983
984 #[cfg(any(std_backtrace, feature = "backtrace"))]
985 pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
986 // This unwrap can only panic if the underlying error's backtrace method
987 // is nondeterministic, which would only happen in maliciously
988 // constructed code.
989 unsafe { this.deref() }
990 .backtrace
991 .as_ref()
992 .or_else(|| {
993 #[cfg(error_generic_member_access)]
994 return nightly::request_ref_backtrace(unsafe { Self::error(this) });
995 #[cfg(not(error_generic_member_access))]
996 return unsafe { (vtable(this.ptr).object_backtrace)(this) };
997 })
998 .expect("backtrace capture failed")
999 }
1000
1001 #[cfg(error_generic_member_access)]
1002 unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
1003 if let Some(backtrace) = unsafe { &this.deref().backtrace } {
1004 nightly::provide_ref_backtrace(request, backtrace);
1005 }
1006 nightly::provide(unsafe { Self::error(this) }, request);
1007 }
1008
1009 #[cold]
1010 pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
1011 Chain::new(unsafe { Self::error(this) })
1012 }
1013}
1014
1015impl<E> StdError for ErrorImpl<E>
1016where
1017 E: StdError,
1018{
1019 fn source(&self) -> Option<&(dyn StdError + 'static)> {
1020 unsafe { ErrorImpl::error(self.erase()).source() }
1021 }
1022
1023 #[cfg(error_generic_member_access)]
1024 fn provide<'a>(&'a self, request: &mut Request<'a>) {
1025 unsafe { ErrorImpl::provide(self.erase(), request) }
1026 }
1027}
1028
1029impl<E> Debug for ErrorImpl<E>
1030where
1031 E: Debug,
1032{
1033 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1034 unsafe { ErrorImpl::debug(self.erase(), formatter) }
1035 }
1036}
1037
1038impl<E> Display for ErrorImpl<E>
1039where
1040 E: Display,
1041{
1042 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1043 unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
1044 }
1045}
1046
1047#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1048impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
1049 #[cold]
1050 fn from(error: Error) -> Self {
1051 error.into_boxed_dyn_error()
1052 }
1053}
1054
1055#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1056impl From<Error> for Box<dyn StdError + Send + 'static> {
1057 #[cold]
1058 fn from(error: Error) -> Self {
1059 error.into_boxed_dyn_error()
1060 }
1061}
1062
1063#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1064impl From<Error> for Box<dyn StdError + 'static> {
1065 #[cold]
1066 fn from(error: Error) -> Self {
1067 error.into_boxed_dyn_error()
1068 }
1069}
1070
1071#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1072impl AsRef<dyn StdError + Send + Sync> for Error {
1073 fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
1074 &**self
1075 }
1076}
1077
1078#[cfg(any(feature = "std", not(anyhow_no_core_error)))]
1079impl AsRef<dyn StdError> for Error {
1080 fn as_ref(&self) -> &(dyn StdError + 'static) {
1081 &**self
1082 }
1083}
1084
1085impl UnwindSafe for Error {}
1086impl RefUnwindSafe for Error {}