//! Traits for working with Errors. #![stable(feature = "rust1", since = "1.0.0")] // A note about crates and the facade: // // Originally, the `Error` trait was defined in libcore, and the impls // were scattered about. However, coherence objected to this // arrangement, because to create the blanket impls for `Box` required // knowing that `&str: !Error`, and we have no means to deal with that // sort of conflict just now. Therefore, for the time being, we have // moved the `Error` trait into libstd. As we evolve a sol'n to the // coherence challenge (e.g., specialization, neg impls, etc) we can // reconsider what crate these items belong in. #[cfg(test)] mod tests; use core::array; use core::convert::Infallible; use crate::alloc::{AllocError, LayoutError}; use crate::any::TypeId; use crate::backtrace::Backtrace; use crate::borrow::Cow; use crate::cell; use crate::char; use crate::fmt::{self, Debug, Display}; use crate::mem::transmute; use crate::num; use crate::str; use crate::string; /// `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, and may provide /// cause chain 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 via `source` chains. /// /// [`Result`]: Result #[stable(feature = "rust1", since = "1.0.0")] 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 { /// side: 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.side) /// } /// } /// /// #[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 { side: 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::() } /// Returns a stack backtrace, if available, of where this error occurred. /// /// This function allows inspecting the location, in code, of where an error /// happened. The returned `Backtrace` contains information about the stack /// trace of the OS thread of execution of where the error originated from. /// /// Note that not all errors contain a `Backtrace`. Also note that a /// `Backtrace` may actually be empty. For more information consult the /// `Backtrace` type itself. #[unstable(feature = "backtrace", issue = "53487")] fn backtrace(&self) -> Option<&Backtrace> { None } /// ``` /// if let Err(e) = "xc".parse::() { /// // Print `e` itself, no need for description(). /// eprintln!("Error: {}", e); /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.42.0", reason = "use the Display impl or to_string()")] fn description(&self) -> &str { "description() is deprecated; use Display" } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( since = "1.33.0", reason = "replaced by Error::source, which can support downcasting" )] #[allow(missing_docs)] fn cause(&self) -> Option<&dyn Error> { self.source() } } 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; } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + 'a> From for Box { /// Converts a type of [`Error`] into a box of dyn [`Error`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::fmt; /// use std::mem; /// /// #[derive(Debug)] /// struct AnError; /// /// impl fmt::Display for AnError { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f , "An error") /// } /// } /// /// impl Error for AnError {} /// /// let an_error = AnError; /// assert!(0 == mem::size_of_val(&an_error)); /// let a_boxed_error = Box::::from(an_error); /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: E) -> Box { Box::new(err) } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + Send + Sync + 'a> From for Box { /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of /// dyn [`Error`] + [`Send`] + [`Sync`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::fmt; /// use std::mem; /// /// #[derive(Debug)] /// struct AnError; /// /// impl fmt::Display for AnError { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// write!(f , "An error") /// } /// } /// /// impl Error for AnError {} /// /// unsafe impl Send for AnError {} /// /// unsafe impl Sync for AnError {} /// /// let an_error = AnError; /// assert!(0 == mem::size_of_val(&an_error)); /// let a_boxed_error = Box::::from(an_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: E) -> Box { Box::new(err) } } #[stable(feature = "rust1", since = "1.0.0")] impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// /// let a_string_error = "a string error".to_string(); /// let a_boxed_error = Box::::from(a_string_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` #[inline] fn from(err: String) -> Box { struct StringError(String); impl Error for StringError { #[allow(deprecated)] fn description(&self) -> &str { &self.0 } } impl Display for StringError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Display::fmt(&self.0, f) } } // Purposefully skip printing "StringError(..)" impl Debug for StringError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Debug::fmt(&self.0, f) } } Box::new(StringError(err)) } } #[stable(feature = "string_box_error", since = "1.6.0")] impl From for Box { /// Converts a [`String`] into a box of dyn [`Error`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// /// let a_string_error = "a string error".to_string(); /// let a_boxed_error = Box::::from(a_string_error); /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(str_err: String) -> Box { let err1: Box = From::from(str_err); let err2: Box = err1; err2 } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a> From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// [`str`]: prim@str /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// /// let a_str_error = "a str error"; /// let a_boxed_error = Box::::from(a_str_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` #[inline] fn from(err: &str) -> Box { From::from(String::from(err)) } } #[stable(feature = "string_box_error", since = "1.6.0")] impl From<&str> for Box { /// Converts a [`str`] into a box of dyn [`Error`]. /// /// [`str`]: prim@str /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// /// let a_str_error = "a str error"; /// let a_boxed_error = Box::::from(a_str_error); /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: &str) -> Box { From::from(String::from(err)) } } #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a, 'b> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); /// let a_boxed_error = Box::::from(a_cow_str_error); /// assert!( /// mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: Cow<'b, str>) -> Box { From::from(String::from(err)) } } #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a> From> for Box { /// Converts a [`Cow`] into a box of dyn [`Error`]. /// /// # Examples /// /// ``` /// use std::error::Error; /// use std::mem; /// use std::borrow::Cow; /// /// let a_cow_str_error = Cow::from("a str error"); /// let a_boxed_error = Box::::from(a_cow_str_error); /// assert!(mem::size_of::>() == mem::size_of_val(&a_boxed_error)) /// ``` fn from(err: Cow<'a, str>) -> Box { From::from(String::from(err)) } } #[unstable(feature = "never_type", issue = "35121")] impl Error for ! {} #[unstable( feature = "allocator_api", reason = "the precise API and guarantees it provides may be tweaked.", issue = "32838" )] impl Error for AllocError {} #[stable(feature = "alloc_layout", since = "1.28.0")] impl Error for LayoutError {} #[stable(feature = "rust1", since = "1.0.0")] impl Error for str::ParseBoolError { #[allow(deprecated)] fn description(&self) -> &str { "failed to parse bool" } } #[stable(feature = "rust1", since = "1.0.0")] impl Error for str::Utf8Error { #[allow(deprecated)] fn description(&self) -> &str { "invalid utf-8: corrupt contents" } } #[stable(feature = "rust1", since = "1.0.0")] impl Error for num::ParseIntError { #[allow(deprecated)] fn description(&self) -> &str { self.__description() } } #[stable(feature = "try_from", since = "1.34.0")] impl Error for num::TryFromIntError { #[allow(deprecated)] fn description(&self) -> &str { self.__description() } } #[stable(feature = "try_from", since = "1.34.0")] impl Error for array::TryFromSliceError { #[allow(deprecated)] fn description(&self) -> &str { self.__description() } } #[stable(feature = "rust1", since = "1.0.0")] impl Error for num::ParseFloatError { #[allow(deprecated)] fn description(&self) -> &str { self.__description() } } #[stable(feature = "rust1", since = "1.0.0")] impl Error for string::FromUtf8Error { #[allow(deprecated)] fn description(&self) -> &str { "invalid utf-8" } } #[stable(feature = "rust1", since = "1.0.0")] impl Error for string::FromUtf16Error { #[allow(deprecated)] fn description(&self) -> &str { "invalid utf-16" } } #[stable(feature = "str_parse_error2", since = "1.8.0")] impl Error for Infallible { fn description(&self) -> &str { match *self {} } } #[stable(feature = "decode_utf16", since = "1.9.0")] impl Error for char::DecodeUtf16Error { #[allow(deprecated)] fn description(&self) -> &str { "unpaired surrogate found" } } #[stable(feature = "box_error", since = "1.8.0")] impl Error for Box { #[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) } } #[stable(feature = "fmt_error", since = "1.11.0")] impl Error for 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 cell::BorrowError { #[allow(deprecated)] fn description(&self) -> &str { "already mutably borrowed" } } #[stable(feature = "try_borrow", since = "1.13.0")] impl Error for cell::BorrowMutError { #[allow(deprecated)] fn description(&self) -> &str { "already borrowed" } } #[stable(feature = "try_from", since = "1.34.0")] impl Error for char::CharTryFromError { #[allow(deprecated)] fn description(&self) -> &str { "converted integer out of range for `char`" } } #[stable(feature = "char_from_str", since = "1.20.0")] impl Error for char::ParseCharError { #[allow(deprecated)] fn description(&self) -> &str { self.__description() } } #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] impl Error for alloc::collections::TryReserveError {} // Copied from `any.rs`. impl dyn Error + 'static { /// Returns `true` if the boxed 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. let boxed = self.type_id(private::Internal); // Compare both `TypeId`s on equality. t == boxed } /// Returns some reference to the boxed 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::() { unsafe { Some(&*(self as *const dyn Error as *const T)) } } else { None } } /// Returns some mutable reference to the boxed 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::() { 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) } } 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) } } impl dyn Error { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempts to downcast the box to a concrete type. pub fn downcast(self: Box) -> Result, Box> { if self.is::() { unsafe { let raw: *mut dyn Error = Box::into_raw(self); Ok(Box::from_raw(raw as *mut T)) } } else { Err(self) } } /// 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.chain(); /// /// 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 chain(&self) -> Chain<'_> { Chain { 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 Chain<'a> { current: Option<&'a (dyn Error + 'static)>, } #[unstable(feature = "error_iter", issue = "58520")] impl<'a> Iterator for Chain<'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 } } impl dyn Error + Send { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempts to downcast the box to a concrete type. pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; ::downcast(err).map_err(|s| unsafe { // Reapply the `Send` marker. transmute::, Box>(s) }) } } impl dyn Error + Send + Sync { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempts to downcast the box to a concrete type. pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; ::downcast(err).map_err(|s| unsafe { // Reapply the `Send + Sync` marker. transmute::, Box>(s) }) } }