#![doc = include_str!("error.md")] #![unstable(feature = "error_in_core", issue = "103765")] #[cfg(test)] mod tests; use crate::any::{Demand, Provider, TypeId}; use crate::fmt::{Debug, Display}; /// `Error` is a trait representing the basic expectations for error values, /// i.e., values of type `E` in [`Result`]. /// /// Errors must describe themselves through the [`Display`] and [`Debug`] /// traits. Error messages are typically concise lowercase sentences without /// trailing punctuation: /// /// ``` /// let err = "NaN".parse::().unwrap_err(); /// assert_eq!(err.to_string(), "invalid digit found in string"); /// ``` /// /// Errors may provide cause information. [`Error::source()`] is generally /// used when errors cross "abstraction boundaries". If one module must report /// an error that is caused by an error from a lower-level module, it can allow /// accessing that error via [`Error::source()`]. This makes it possible for the /// high-level module to provide its own errors while also revealing some of the /// implementation for debugging. #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Error")] #[rustc_has_incoherent_inherent_impls] #[cfg_attr(not(bootstrap), allow(multiple_supertrait_upcastable))] pub trait Error: Debug + Display { /// The lower-level source of this error, if any. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::fmt; /// /// #[derive(Debug)] /// struct SuperError { /// source: SuperErrorSideKick, /// } /// /// impl fmt::Display for SuperError { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "SuperError is here!") /// } /// } /// /// impl Error for SuperError { /// fn source(&self) -> Option<&(dyn Error + 'static)> { /// Some(&self.source) /// } /// } /// /// #[derive(Debug)] /// struct SuperErrorSideKick; /// /// impl fmt::Display for SuperErrorSideKick { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "SuperErrorSideKick is here!") /// } /// } /// /// impl Error for SuperErrorSideKick {} /// /// fn get_super_error() -> Result<(), SuperError> { /// Err(SuperError { source: SuperErrorSideKick }) /// } /// /// fn main() { /// match get_super_error() { /// Err(e) => { /// println!("Error: {e}"); /// println!("Caused by: {}", e.source().unwrap()); /// } /// _ => println!("No error"), /// } /// } /// ``` #[stable(feature = "error_source", since = "1.30.0")] fn source(&self) -> Option<&(dyn Error + 'static)> { None } /// Gets the `TypeId` of `self`. #[doc(hidden)] #[unstable( feature = "error_type_id", reason = "this is memory-unsafe to override in user code", issue = "60784" )] fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static, { TypeId::of::() } /// ``` /// if let Err(e) = "xc".parse::() { /// // Print `e` itself, no need for description(). /// eprintln!("Error: {e}"); /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")] fn description(&self) -> &str { "description() is deprecated; use Display" } #[stable(feature = "rust1", since = "1.0.0")] #[deprecated( since = "1.33.0", note = "replaced by Error::source, which can support downcasting" )] #[allow(missing_docs)] fn cause(&self) -> Option<&dyn Error> { self.source() } /// Provides type based access to context intended for error reports. /// /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract /// references to member variables from `dyn Error` trait objects. /// /// # Example /// /// ```rust /// #![feature(provide_any)] /// #![feature(error_generic_member_access)] /// use core::fmt; /// use core::any::Demand; /// /// #[derive(Debug)] /// struct MyBacktrace { /// // ... /// } /// /// impl MyBacktrace { /// fn new() -> MyBacktrace { /// // ... /// # MyBacktrace {} /// } /// } /// /// #[derive(Debug)] /// struct SourceError { /// // ... /// } /// /// impl fmt::Display for SourceError { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "Example Source Error") /// } /// } /// /// impl std::error::Error for SourceError {} /// /// #[derive(Debug)] /// struct Error { /// source: SourceError, /// backtrace: MyBacktrace, /// } /// /// impl fmt::Display for Error { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "Example Error") /// } /// } /// /// impl std::error::Error for Error { /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { /// demand /// .provide_ref::(&self.backtrace) /// .provide_ref::(&self.source); /// } /// } /// /// fn main() { /// let backtrace = MyBacktrace::new(); /// let source = SourceError {}; /// let error = Error { source, backtrace }; /// let dyn_error = &error as &dyn std::error::Error; /// let backtrace_ref = dyn_error.request_ref::().unwrap(); /// /// assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); /// } /// ``` #[unstable(feature = "error_generic_member_access", issue = "99301")] #[allow(unused_variables)] fn provide<'a>(&'a self, demand: &mut Demand<'a>) {} } #[unstable(feature = "error_generic_member_access", issue = "99301")] impl Provider for E where E: Error + ?Sized, { fn provide<'a>(&'a self, demand: &mut Demand<'a>) { self.provide(demand) } } mod private { // This is a hack to prevent `type_id` from being overridden by `Error` // implementations, since that can enable unsound downcasting. #[unstable(feature = "error_type_id", issue = "60784")] #[derive(Debug)] pub struct Internal; } #[unstable(feature = "never_type", issue = "35121")] impl Error for ! {} impl<'a> dyn Error + 'a { /// Request a reference of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_ref(&'a self) -> Option<&'a T> { core::any::request_ref(self) } /// Request a value of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_value(&'a self) -> Option { core::any::request_value(self) } } // Copied from `any.rs`. impl dyn Error + 'static { /// Returns `true` if the inner type is the same as `T`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn is(&self) -> bool { // Get `TypeId` of the type this function is instantiated with. let t = TypeId::of::(); // Get `TypeId` of the type in the trait object (`self`). let concrete = self.type_id(private::Internal); // Compare both `TypeId`s on equality. t == concrete } /// Returns some reference to the inner value if it is of type `T`, or /// `None` if it isn't. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_ref(&self) -> Option<&T> { if self.is::() { // SAFETY: `is` ensures this type cast is correct unsafe { Some(&*(self as *const dyn Error as *const T)) } } else { None } } /// Returns some mutable reference to the inner value if it is of type `T`, or /// `None` if it isn't. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_mut(&mut self) -> Option<&mut T> { if self.is::() { // SAFETY: `is` ensures this type cast is correct unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) } } else { None } } } impl dyn Error + 'static + Send { /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn is(&self) -> bool { ::is::(self) } /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_ref(&self) -> Option<&T> { ::downcast_ref::(self) } /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_mut(&mut self) -> Option<&mut T> { ::downcast_mut::(self) } /// Request a reference of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_ref(&self) -> Option<&T> { ::request_ref(self) } /// Request a value of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_value(&self) -> Option { ::request_value(self) } } impl dyn Error + 'static + Send + Sync { /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn is(&self) -> bool { ::is::(self) } /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_ref(&self) -> Option<&T> { ::downcast_ref::(self) } /// Forwards to the method defined on the type `dyn Error`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_mut(&mut self) -> Option<&mut T> { ::downcast_mut::(self) } /// Request a reference of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_ref(&self) -> Option<&T> { ::request_ref(self) } /// Request a value of type `T` as context about this error. #[unstable(feature = "error_generic_member_access", issue = "99301")] pub fn request_value(&self) -> Option { ::request_value(self) } } impl dyn Error { /// Returns an iterator starting with the current error and continuing with /// recursively calling [`Error::source`]. /// /// If you want to omit the current error and only use its sources, /// use `skip(1)`. /// /// # Examples /// /// ``` /// #![feature(error_iter)] /// use std::error::Error; /// use std::fmt; /// /// #[derive(Debug)] /// struct A; /// /// #[derive(Debug)] /// struct B(Option>); /// /// impl fmt::Display for A { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "A") /// } /// } /// /// impl fmt::Display for B { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f, "B") /// } /// } /// /// impl Error for A {} /// /// impl Error for B { /// fn source(&self) -> Option<&(dyn Error + 'static)> { /// self.0.as_ref().map(|e| e.as_ref()) /// } /// } /// /// let b = B(Some(Box::new(A))); /// /// // let err : Box = b.into(); // or /// let err = &b as &(dyn Error); /// /// let mut iter = err.sources(); /// /// assert_eq!("B".to_string(), iter.next().unwrap().to_string()); /// assert_eq!("A".to_string(), iter.next().unwrap().to_string()); /// assert!(iter.next().is_none()); /// assert!(iter.next().is_none()); /// ``` #[unstable(feature = "error_iter", issue = "58520")] #[inline] pub fn sources(&self) -> Source<'_> { // You may think this method would be better in the Error trait, and you'd be right. // Unfortunately that doesn't work, not because of the object safety rules but because we // save a reference to self in Sources below as a trait object. If this method was // declared in Error, then self would have the type &T where T is some concrete type which // implements Error. We would need to coerce self to have type &dyn Error, but that requires // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error // since that would forbid Error trait objects, and we can't put that bound on the method // because that means the method can't be called on trait objects (we'd also need the // 'static bound, but that isn't allowed because methods with bounds on Self other than // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible. Source { current: Some(self) } } } /// An iterator over an [`Error`] and its sources. /// /// If you want to omit the initial error and only process /// its sources, use `skip(1)`. #[unstable(feature = "error_iter", issue = "58520")] #[derive(Clone, Debug)] pub struct Source<'a> { current: Option<&'a (dyn Error + 'static)>, } #[unstable(feature = "error_iter", issue = "58520")] impl<'a> Iterator for Source<'a> { type Item = &'a (dyn Error + 'static); fn next(&mut self) -> Option { let current = self.current; self.current = self.current.and_then(Error::source); current } } #[stable(feature = "error_by_ref", since = "1.51.0")] impl<'a, T: Error + ?Sized> Error for &'a T { #[allow(deprecated, deprecated_in_future)] fn description(&self) -> &str { Error::description(&**self) } #[allow(deprecated)] fn cause(&self) -> Option<&dyn Error> { Error::cause(&**self) } fn source(&self) -> Option<&(dyn Error + 'static)> { Error::source(&**self) } fn provide<'b>(&'b self, demand: &mut Demand<'b>) { Error::provide(&**self, demand); } } #[stable(feature = "fmt_error", since = "1.11.0")] impl Error for crate::fmt::Error { #[allow(deprecated)] fn description(&self) -> &str { "an error occurred when formatting an argument" } } #[stable(feature = "try_borrow", since = "1.13.0")] impl Error for crate::cell::BorrowError { #[allow(deprecated)] fn description(&self) -> &str { "already mutably borrowed" } } #[stable(feature = "try_borrow", since = "1.13.0")] impl Error for crate::cell::BorrowMutError { #[allow(deprecated)] fn description(&self) -> &str { "already borrowed" } } #[stable(feature = "try_from", since = "1.34.0")] impl Error for crate::char::CharTryFromError { #[allow(deprecated)] fn description(&self) -> &str { "converted integer out of range for `char`" } } #[stable(feature = "duration_checked_float", since = "1.66.0")] impl Error for crate::time::TryFromFloatSecsError {} #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] impl Error for crate::ffi::FromBytesUntilNulError {} #[unstable(feature = "get_many_mut", issue = "104642")] impl Error for crate::slice::GetManyMutError {}