1 //! An experimental new error-handling library. Guide-style introduction
2 //! is available [here](https://boats.gitlab.io/failure/).
4 //! The primary items exported by this library are:
6 //! - `Fail`: a new trait for custom error types in Rust.
7 //! - `Error`: a wrapper around `Fail` types to make it easy to coalesce them
10 //! As a general rule, library authors should create their own error types and
11 //! implement `Fail` for them, whereas application authors should primarily
12 //! deal with the `Error` type. There are exceptions to this rule, though, in
13 //! both directions, and users should do whatever seems most appropriate to
18 //! Backtraces are disabled by default. To turn backtraces on, enable
19 //! the `backtrace` Cargo feature and set the `RUST_BACKTRACE` environment
20 //! variable to a non-zero value (this also enables backtraces for panics).
21 //! Use the `RUST_FAILURE_BACKTRACE` variable to enable or disable backtraces
22 //! for `failure` specifically.
23 #![cfg_attr(not(feature = "std"), no_std)]
24 #![deny(missing_docs)]
26 #![cfg_attr(feature = "small-error", feature(extern_types, allocator_api))]
28 macro_rules
! with_std { ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*) }
29 macro_rules
! without_std { ($($i:item)*) => ($(#[cfg(not(feature = "std"))]$i)*) }
31 // Re-export libcore using an alias so that the macros can work without
32 // requiring `extern crate core` downstream.
34 pub extern crate core
as _core
;
38 #[cfg(feature = "std")]
44 use core
::any
::TypeId
;
45 use core
::fmt
::{Debug, Display}
;
47 pub use as_fail
::AsFail
;
48 pub use backtrace
::Backtrace
;
49 pub use compat
::Compat
;
50 pub use context
::Context
;
51 pub use result_ext
::ResultExt
;
53 #[cfg(feature = "failure_derive")]
54 #[allow(unused_imports)]
56 extern crate failure_derive
;
58 #[cfg(feature = "failure_derive")]
60 pub use failure_derive
::*;
66 pub use sync_failure
::SyncFailure
;
70 use std
::error
::Error
as StdError
;
74 /// A common result with an `Error`.
75 pub type Fallible
<T
> = Result
<T
, Error
>;
79 pub use error_message
::err_msg
;
84 /// Implementors of this trait are called 'failures'.
86 /// All error types should implement `Fail`, which provides a baseline of
87 /// functionality that they all share.
89 /// `Fail` has no required methods, but it does require that your type
90 /// implement several other traits:
92 /// - `Display`: to print a user-friendly representation of the error.
93 /// - `Debug`: to print a verbose, developer-focused representation of the
95 /// - `Send + Sync`: Your error type is required to be safe to transfer to and
96 /// reference from another thread
98 /// Additionally, all failures must be `'static`. This enables downcasting.
100 /// `Fail` provides several methods with default implementations. Two of these
101 /// may be appropriate to override depending on the definition of your
102 /// particular failure: the `cause` and `backtrace` methods.
104 /// The `failure_derive` crate provides a way to derive the `Fail` trait for
105 /// your type. Additionally, all types that already implement
106 /// `std::error::Error`, and are also `Send`, `Sync`, and `'static`, implement
107 /// `Fail` by a blanket impl.
108 pub trait Fail
: Display
+ Debug
+ Send
+ Sync
+ '
static {
109 /// Returns the "name" of the error.
111 /// This is typically the type name. Not all errors will implement
112 /// this. This method is expected to be most useful in situations
113 /// where errors need to be reported to external instrumentation systems
114 /// such as crash reporters.
115 fn name(&self) -> Option
<&str> {
119 /// Returns a reference to the underlying cause of this failure, if it
120 /// is an error that wraps other errors.
122 /// Returns `None` if this failure does not have another error as its
123 /// underlying cause. By default, this returns `None`.
125 /// This should **never** return a reference to `self`, but only return
126 /// `Some` when it can return a **different** failure. Users may loop
127 /// over the cause chain, and returning `self` would result in an infinite
129 fn cause(&self) -> Option
<&Fail
> {
133 /// Returns a reference to the `Backtrace` carried by this failure, if it
136 /// Returns `None` if this failure does not carry a backtrace. By
137 /// default, this returns `None`.
138 fn backtrace(&self) -> Option
<&Backtrace
> {
142 /// Provides context for this failure.
144 /// This can provide additional information about this error, appropriate
145 /// to the semantics of the current layer. That is, if you have a
146 /// lower-level error, such as an IO error, you can provide additional context
147 /// about what that error means in the context of your function. This
148 /// gives users of this function more information about what has gone
151 /// This takes any type that implements `Display`, as well as
152 /// `Send`/`Sync`/`'static`. In practice, this means it can take a `String`
153 /// or a string literal, or another failure, or some other custom context-carrying
155 fn context
<D
>(self, context
: D
) -> Context
<D
>
157 D
: Display
+ Send
+ Sync
+ '
static,
160 Context
::with_err(context
, self)
163 /// Wraps this failure in a compatibility wrapper that implements
164 /// `std::error::Error`.
166 /// This allows failures to be compatible with older crates that
167 /// expect types that implement the `Error` trait from `std::error`.
168 fn compat(self) -> Compat
<Self>
172 Compat { error: self }
176 #[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
177 fn causes(&self) -> Causes
181 Causes { fail: Some(self) }
187 note
= "please use the 'find_root_cause()' method instead"
189 fn root_cause(&self) -> &Fail
193 find_root_cause(self)
197 fn __private_get_type_id__(&self) -> TypeId
{
203 /// Attempts to downcast this failure to a concrete type by reference.
205 /// If the underlying error is not of type `T`, this will return `None`.
206 pub fn downcast_ref
<T
: Fail
>(&self) -> Option
<&T
> {
207 if self.__private_get_type_id__() == TypeId
::of
::<T
>() {
208 unsafe { Some(&*(self as *const Fail as *const T)) }
214 /// Attempts to downcast this failure to a concrete type by mutable
217 /// If the underlying error is not of type `T`, this will return `None`.
218 pub fn downcast_mut
<T
: Fail
>(&mut self) -> Option
<&mut T
> {
219 if self.__private_get_type_id__() == TypeId
::of
::<T
>() {
220 unsafe { Some(&mut *(self as *mut Fail as *mut T)) }
226 /// Returns the "root cause" of this `Fail` - the last value in the
227 /// cause chain which does not return an underlying `cause`.
229 /// If this type does not have a cause, `self` is returned, because
230 /// it is its own root cause.
232 /// This is equivalent to iterating over `iter_causes()` and taking
234 pub fn find_root_cause(&self) -> &Fail
{
235 find_root_cause(self)
238 /// Returns a iterator over the causes of this `Fail` with the cause
239 /// of this fail as the first item and the `root_cause` as the final item.
241 /// Use `iter_chain` to also include the fail itself.
242 pub fn iter_causes(&self) -> Causes
{
243 Causes { fail: self.cause() }
246 /// Returns a iterator over all fails up the chain from the current
247 /// as the first item up to the `root_cause` as the final item.
249 /// This means that the chain also includes the fail itself which
250 /// means that it does *not* start with `cause`. To skip the outermost
251 /// fail use `iter_causes` instead.
252 pub fn iter_chain(&self) -> Causes
{
253 Causes { fail: Some(self) }
256 /// Deprecated alias to `find_root_cause`.
259 note
= "please use the 'find_root_cause()' method instead"
261 pub fn root_cause(&self) -> &Fail
{
262 find_root_cause(self)
265 /// Deprecated alias to `iter_chain`.
266 #[deprecated(since = "0.1.2", note = "please use the 'iter_chain()' method instead")]
267 pub fn causes(&self) -> Causes
{
268 Causes { fail: Some(self) }
272 #[cfg(feature = "std")]
273 impl<E
: StdError
+ Send
+ Sync
+ '
static> Fail
for E {}
275 #[cfg(feature = "std")]
276 impl Fail
for Box
<Fail
> {
277 fn cause(&self) -> Option
<&Fail
> {
281 fn backtrace(&self) -> Option
<&Backtrace
> {
286 /// A iterator over the causes of a `Fail`
287 pub struct Causes
<'f
> {
288 fail
: Option
<&'f Fail
>,
291 impl<'f
> Iterator
for Causes
<'f
> {
292 type Item
= &'f Fail
;
293 fn next(&mut self) -> Option
<&'f Fail
> {
294 self.fail
.map(|fail
| {
295 self.fail
= fail
.cause();
301 fn find_root_cause(mut fail
: &Fail
) -> &Fail
{
302 while let Some(cause
) = fail
.cause() {