1 #![doc = include_str!("error.md")]
2 #![unstable(feature = "error_in_core", issue = "103765")]
7 use crate::any::{Demand, Provider, TypeId};
8 use crate::fmt::{Debug, Display};
10 /// `Error` is a trait representing the basic expectations for error values,
11 /// i.e., values of type `E` in [`Result<T, E>`].
13 /// Errors must describe themselves through the [`Display`] and [`Debug`]
14 /// traits. Error messages are typically concise lowercase sentences without
15 /// trailing punctuation:
18 /// let err = "NaN".parse::<u32>().unwrap_err();
19 /// assert_eq!(err.to_string(), "invalid digit found in string");
22 /// Errors may provide cause information. [`Error::source()`] is generally
23 /// used when errors cross "abstraction boundaries". If one module must report
24 /// an error that is caused by an error from a lower-level module, it can allow
25 /// accessing that error via [`Error::source()`]. This makes it possible for the
26 /// high-level module to provide its own errors while also revealing some of the
27 /// implementation for debugging.
28 #[stable(feature = "rust1", since = "1.0.0")]
29 #[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
30 #[rustc_has_incoherent_inherent_impls]
31 #[cfg_attr(not(bootstrap), allow(multiple_supertrait_upcastable))]
32 pub trait Error: Debug + Display {
33 /// The lower-level source of this error, if any.
38 /// use std::error::Error;
42 /// struct SuperError {
43 /// source: SuperErrorSideKick,
46 /// impl fmt::Display for SuperError {
47 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 /// write!(f, "SuperError is here!")
52 /// impl Error for SuperError {
53 /// fn source(&self) -> Option<&(dyn Error + 'static)> {
54 /// Some(&self.source)
59 /// struct SuperErrorSideKick;
61 /// impl fmt::Display for SuperErrorSideKick {
62 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 /// write!(f, "SuperErrorSideKick is here!")
67 /// impl Error for SuperErrorSideKick {}
69 /// fn get_super_error() -> Result<(), SuperError> {
70 /// Err(SuperError { source: SuperErrorSideKick })
74 /// match get_super_error() {
76 /// println!("Error: {e}");
77 /// println!("Caused by: {}", e.source().unwrap());
79 /// _ => println!("No error"),
83 #[stable(feature = "error_source", since = "1.30.0")]
84 fn source(&self) -> Option<&(dyn Error + 'static)> {
88 /// Gets the `TypeId` of `self`.
91 feature = "error_type_id",
92 reason = "this is memory-unsafe to override in user code",
95 fn type_id(&self, _: private::Internal) -> TypeId
103 /// if let Err(e) = "xc".parse::<u32>() {
104 /// // Print `e` itself, no need for description().
105 /// eprintln!("Error: {e}");
108 #[stable(feature = "rust1", since = "1.0.0")]
109 #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
110 fn description(&self) -> &str {
111 "description() is deprecated; use Display"
114 #[stable(feature = "rust1", since = "1.0.0")]
117 note = "replaced by Error::source, which can support downcasting"
119 #[allow(missing_docs)]
120 fn cause(&self) -> Option<&dyn Error> {
124 /// Provides type based access to context intended for error reports.
126 /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
127 /// references to member variables from `dyn Error` trait objects.
132 /// #![feature(provide_any)]
133 /// #![feature(error_generic_member_access)]
135 /// use core::any::Demand;
138 /// struct MyBacktrace {
142 /// impl MyBacktrace {
143 /// fn new() -> MyBacktrace {
150 /// struct SourceError {
154 /// impl fmt::Display for SourceError {
155 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 /// write!(f, "Example Source Error")
160 /// impl std::error::Error for SourceError {}
164 /// source: SourceError,
165 /// backtrace: MyBacktrace,
168 /// impl fmt::Display for Error {
169 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 /// write!(f, "Example Error")
174 /// impl std::error::Error for Error {
175 /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
177 /// .provide_ref::<MyBacktrace>(&self.backtrace)
178 /// .provide_ref::<dyn std::error::Error + 'static>(&self.source);
183 /// let backtrace = MyBacktrace::new();
184 /// let source = SourceError {};
185 /// let error = Error { source, backtrace };
186 /// let dyn_error = &error as &dyn std::error::Error;
187 /// let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
189 /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
192 #[unstable(feature = "error_generic_member_access", issue = "99301")]
193 #[allow(unused_variables)]
194 fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
197 #[unstable(feature = "error_generic_member_access", issue = "99301")]
198 impl<E> Provider for E
202 fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
208 // This is a hack to prevent `type_id` from being overridden by `Error`
209 // implementations, since that can enable unsound downcasting.
210 #[unstable(feature = "error_type_id", issue = "60784")]
215 #[unstable(feature = "never_type", issue = "35121")]
218 impl<'a> dyn Error + 'a {
219 /// Request a reference of type `T` as context about this error.
220 #[unstable(feature = "error_generic_member_access", issue = "99301")]
221 pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
222 core::any::request_ref(self)
225 /// Request a value of type `T` as context about this error.
226 #[unstable(feature = "error_generic_member_access", issue = "99301")]
227 pub fn request_value<T: 'static>(&'a self) -> Option<T> {
228 core::any::request_value(self)
232 // Copied from `any.rs`.
233 impl dyn Error + 'static {
234 /// Returns `true` if the inner type is the same as `T`.
235 #[stable(feature = "error_downcast", since = "1.3.0")]
237 pub fn is<T: Error + 'static>(&self) -> bool {
238 // Get `TypeId` of the type this function is instantiated with.
239 let t = TypeId::of::<T>();
241 // Get `TypeId` of the type in the trait object (`self`).
242 let concrete = self.type_id(private::Internal);
244 // Compare both `TypeId`s on equality.
248 /// Returns some reference to the inner value if it is of type `T`, or
249 /// `None` if it isn't.
250 #[stable(feature = "error_downcast", since = "1.3.0")]
252 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
254 // SAFETY: `is` ensures this type cast is correct
255 unsafe { Some(&*(self as *const dyn Error as *const T)) }
261 /// Returns some mutable reference to the inner value if it is of type `T`, or
262 /// `None` if it isn't.
263 #[stable(feature = "error_downcast", since = "1.3.0")]
265 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
267 // SAFETY: `is` ensures this type cast is correct
268 unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
275 impl dyn Error + 'static + Send {
276 /// Forwards to the method defined on the type `dyn Error`.
277 #[stable(feature = "error_downcast", since = "1.3.0")]
279 pub fn is<T: Error + 'static>(&self) -> bool {
280 <dyn Error + 'static>::is::<T>(self)
283 /// Forwards to the method defined on the type `dyn Error`.
284 #[stable(feature = "error_downcast", since = "1.3.0")]
286 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
287 <dyn Error + 'static>::downcast_ref::<T>(self)
290 /// Forwards to the method defined on the type `dyn Error`.
291 #[stable(feature = "error_downcast", since = "1.3.0")]
293 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
294 <dyn Error + 'static>::downcast_mut::<T>(self)
297 /// Request a reference of type `T` as context about this error.
298 #[unstable(feature = "error_generic_member_access", issue = "99301")]
299 pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
300 <dyn Error>::request_ref(self)
303 /// Request a value of type `T` as context about this error.
304 #[unstable(feature = "error_generic_member_access", issue = "99301")]
305 pub fn request_value<T: 'static>(&self) -> Option<T> {
306 <dyn Error>::request_value(self)
310 impl dyn Error + 'static + Send + Sync {
311 /// Forwards to the method defined on the type `dyn Error`.
312 #[stable(feature = "error_downcast", since = "1.3.0")]
314 pub fn is<T: Error + 'static>(&self) -> bool {
315 <dyn Error + 'static>::is::<T>(self)
318 /// Forwards to the method defined on the type `dyn Error`.
319 #[stable(feature = "error_downcast", since = "1.3.0")]
321 pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
322 <dyn Error + 'static>::downcast_ref::<T>(self)
325 /// Forwards to the method defined on the type `dyn Error`.
326 #[stable(feature = "error_downcast", since = "1.3.0")]
328 pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
329 <dyn Error + 'static>::downcast_mut::<T>(self)
332 /// Request a reference of type `T` as context about this error.
333 #[unstable(feature = "error_generic_member_access", issue = "99301")]
334 pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
335 <dyn Error>::request_ref(self)
338 /// Request a value of type `T` as context about this error.
339 #[unstable(feature = "error_generic_member_access", issue = "99301")]
340 pub fn request_value<T: 'static>(&self) -> Option<T> {
341 <dyn Error>::request_value(self)
346 /// Returns an iterator starting with the current error and continuing with
347 /// recursively calling [`Error::source`].
349 /// If you want to omit the current error and only use its sources,
355 /// #![feature(error_iter)]
356 /// use std::error::Error;
363 /// struct B(Option<Box<dyn Error + 'static>>);
365 /// impl fmt::Display for A {
366 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371 /// impl fmt::Display for B {
372 /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377 /// impl Error for A {}
379 /// impl Error for B {
380 /// fn source(&self) -> Option<&(dyn Error + 'static)> {
381 /// self.0.as_ref().map(|e| e.as_ref())
385 /// let b = B(Some(Box::new(A)));
387 /// // let err : Box<Error> = b.into(); // or
388 /// let err = &b as &(dyn Error);
390 /// let mut iter = err.sources();
392 /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
393 /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
394 /// assert!(iter.next().is_none());
395 /// assert!(iter.next().is_none());
397 #[unstable(feature = "error_iter", issue = "58520")]
399 pub fn sources(&self) -> Source<'_> {
400 // You may think this method would be better in the Error trait, and you'd be right.
401 // Unfortunately that doesn't work, not because of the object safety rules but because we
402 // save a reference to self in Sources below as a trait object. If this method was
403 // declared in Error, then self would have the type &T where T is some concrete type which
404 // implements Error. We would need to coerce self to have type &dyn Error, but that requires
405 // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
406 // since that would forbid Error trait objects, and we can't put that bound on the method
407 // because that means the method can't be called on trait objects (we'd also need the
408 // 'static bound, but that isn't allowed because methods with bounds on Self other than
409 // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
411 Source { current: Some(self) }
415 /// An iterator over an [`Error`] and its sources.
417 /// If you want to omit the initial error and only process
418 /// its sources, use `skip(1)`.
419 #[unstable(feature = "error_iter", issue = "58520")]
420 #[derive(Clone, Debug)]
421 pub struct Source<'a> {
422 current: Option<&'a (dyn Error + 'static)>,
425 #[unstable(feature = "error_iter", issue = "58520")]
426 impl<'a> Iterator for Source<'a> {
427 type Item = &'a (dyn Error + 'static);
429 fn next(&mut self) -> Option<Self::Item> {
430 let current = self.current;
431 self.current = self.current.and_then(Error::source);
436 #[stable(feature = "error_by_ref", since = "1.51.0")]
437 impl<'a, T: Error + ?Sized> Error for &'a T {
438 #[allow(deprecated, deprecated_in_future)]
439 fn description(&self) -> &str {
440 Error::description(&**self)
444 fn cause(&self) -> Option<&dyn Error> {
445 Error::cause(&**self)
448 fn source(&self) -> Option<&(dyn Error + 'static)> {
449 Error::source(&**self)
452 fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
453 Error::provide(&**self, demand);
457 #[stable(feature = "fmt_error", since = "1.11.0")]
458 impl Error for crate::fmt::Error {
460 fn description(&self) -> &str {
461 "an error occurred when formatting an argument"
465 #[stable(feature = "try_borrow", since = "1.13.0")]
466 impl Error for crate::cell::BorrowError {
468 fn description(&self) -> &str {
469 "already mutably borrowed"
473 #[stable(feature = "try_borrow", since = "1.13.0")]
474 impl Error for crate::cell::BorrowMutError {
476 fn description(&self) -> &str {
481 #[stable(feature = "try_from", since = "1.34.0")]
482 impl Error for crate::char::CharTryFromError {
484 fn description(&self) -> &str {
485 "converted integer out of range for `char`"
489 #[stable(feature = "char_from_str", since = "1.20.0")]
490 impl Error for crate::char::ParseCharError {
492 fn description(&self) -> &str {
497 #[stable(feature = "duration_checked_float", since = "1.66.0")]
498 impl Error for crate::time::TryFromFloatSecsError {}
500 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
501 impl Error for crate::ffi::FromBytesWithNulError {
503 fn description(&self) -> &str {
508 #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
509 impl Error for crate::ffi::FromBytesUntilNulError {}
511 #[unstable(feature = "get_many_mut", issue = "104642")]
512 impl<const N: usize> Error for crate::slice::GetManyMutError<N> {}