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