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(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 ≥
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 — 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<anyhow::Error>
572 /// for Box<dyn Error + Send + Sync + 'static></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 = 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(ptr::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(ptr::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 {}