error_chain/
lib.rs

1#![deny(missing_docs)]
2#![doc(html_root_url = "https://docs.rs/error-chain/0.12.4")]
3
4//! A library for consistent and reliable error handling
5//!
6//! error-chain makes it easy to take full advantage of Rust's
7//! powerful error handling features without the overhead of
8//! maintaining boilerplate error types and conversions. It implements
9//! an opinionated strategy for defining your own error types, as well
10//! as conversions from others' error types.
11//!
12//! ## Quick start
13//!
14//! If you just want to set up your new project with error-chain,
15//! follow the [quickstart.rs] template, and read this [intro]
16//! to error-chain.
17//!
18//! [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
19//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
20//!
21//! ## Why error chain?
22//!
23//! * error-chain is easy to configure. Handle errors robustly with minimal
24//!   effort.
25//! * Basic error handling requires no maintenance of custom error types
26//!   nor the [`From`] conversions that make `?` work.
27//! * error-chain scales from simple error handling strategies to more
28//!   rigorous.  Return formatted strings for simple errors, only
29//!   introducing error variants and their strong typing as needed for
30//!   advanced error recovery.
31//! * error-chain makes it trivial to correctly manage the [cause] of
32//!   the errors generated by your own code. This is the "chaining"
33//!   in "error-chain".
34//!
35//! [cause]: https://doc.rust-lang.org/std/error/trait.Error.html#method.cause
36//!
37//! ## Principles of error-chain
38//!
39//! error-chain is based on the following principles:
40//!
41//! * No error should ever be discarded. This library primarily
42//!   makes it easy to "chain" errors with the [`chain_err`] method.
43//! * Introducing new errors is trivial. Simple errors can be introduced
44//!   at the error site with just a string.
45//! * Handling errors is possible with pattern matching.
46//! * Conversions between error types are done in an automatic and
47//!   consistent way - [`From`] conversion behavior is never specified
48//!   explicitly.
49//! * Errors implement [`Send`].
50//! * Errors can carry backtraces.
51//!
52//! Similar to other libraries like [error-type] and [quick-error],
53//! this library introduces the error chaining mechanism originally
54//! employed by Cargo.  The [`error_chain!`] macro declares the types
55//! and implementation boilerplate necessary for fulfilling a
56//! particular error-handling strategy. Most importantly it defines a
57//! custom error type (called [`Error`] by convention) and the [`From`]
58//! conversions that let the `?` operator work.
59//!
60//! This library differs in a few ways from previous error libs:
61//!
62//! * Instead of defining the custom [`Error`] type as an enum, it is a
63//!   struct containing an [`ErrorKind`][] (which defines the
64//!   [`description`] and [`display_chain`] methods for the error), an opaque,
65//!   optional, boxed [`std::error::Error`]` + `[`Send`]` + 'static` object
66//!   (which defines the [`cause`], and establishes the links in the
67//!   error chain), and a [`Backtrace`].
68//! * The macro also defines a [`ResultExt`] trait that defines a
69//!   [`chain_err`] method. This method on all [`std::error::Error`]` + `[`Send`]` + 'static`
70//!   types extends the error chain by boxing the current
71//!   error into an opaque object and putting it inside a new concrete
72//!   error.
73//! * It provides automatic [`From`] conversions between other error types
74//!   defined by the [`error_chain!`] that preserve type information,
75//!   and facilitate seamless error composition and matching of composed
76//!   errors.
77//! * It provides automatic [`From`] conversions between any other error
78//!   type that hides the type of the other error in the [`cause`] box.
79//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
80//!   the earliest opportunity and propagates it down the stack through
81//!   [`From`] and [`ResultExt`] conversions.
82//!
83//! To accomplish its goals it makes some tradeoffs:
84//!
85//! * The split between the [`Error`] and [`ErrorKind`] types can make it
86//!   slightly more cumbersome to instantiate new (unchained) errors,
87//!   requiring an [`Into`] or [`From`] conversion; as well as slightly
88//!   more cumbersome to match on errors with another layer of types
89//!   to match.
90//! * Because the error type contains [`std::error::Error`]` + `[`Send`]` + 'static` objects,
91//!   it can't implement [`PartialEq`] for easy comparisons.
92//!
93//! ## Declaring error types
94//!
95//! Generally, you define one family of error types per crate, though
96//! it's also perfectly fine to define error types on a finer-grained
97//! basis, such as per module.
98//!
99//! Assuming you are using crate-level error types, typically you will
100//! define an `errors` module and inside it call [`error_chain!`]:
101//!
102//! ```
103//! # #[macro_use] extern crate error_chain;
104//! mod other_error {
105//!     error_chain! {}
106//! }
107//!
108//! error_chain! {
109//!     // The type defined for this error. These are the conventional
110//!     // and recommended names, but they can be arbitrarily chosen.
111//!     //
112//!     // It is also possible to leave this section out entirely, or
113//!     // leave it empty, and these names will be used automatically.
114//!     types {
115//!         Error, ErrorKind, ResultExt, Result;
116//!     }
117//!
118//!     // Without the `Result` wrapper:
119//!     //
120//!     // types {
121//!     //     Error, ErrorKind, ResultExt;
122//!     // }
123//!
124//!     // Automatic conversions between this error chain and other
125//!     // error chains. In this case, it will e.g. generate an
126//!     // `ErrorKind` variant called `Another` which in turn contains
127//!     // the `other_error::ErrorKind`, with conversions from
128//!     // `other_error::Error`.
129//!     //
130//!     // Optionally, some attributes can be added to a variant.
131//!     //
132//!     // This section can be empty.
133//!     links {
134//!         Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
135//!     }
136//!
137//!     // Automatic conversions between this error chain and other
138//!     // error types not defined by the `error_chain!`. These will be
139//!     // wrapped in a new error with, in the first case, the
140//!     // `ErrorKind::Fmt` variant. The description and cause will
141//!     // forward to the description and cause of the original error.
142//!     //
143//!     // Optionally, some attributes can be added to a variant.
144//!     //
145//!     // This section can be empty.
146//!     foreign_links {
147//!         Fmt(::std::fmt::Error);
148//!         Io(::std::io::Error) #[cfg(unix)];
149//!     }
150//!
151//!     // Define additional `ErrorKind` variants.  Define custom responses with the
152//!     // `description` and `display` calls.
153//!     errors {
154//!         InvalidToolchainName(t: String) {
155//!             description("invalid toolchain name")
156//!             display("invalid toolchain name: '{}'", t)
157//!         }
158//!
159//!         // You can also add commas after description/display.
160//!         // This may work better with some editor auto-indentation modes:
161//!         UnknownToolchainVersion(v: String) {
162//!             description("unknown toolchain version"), // note the ,
163//!             display("unknown toolchain version: '{}'", v), // trailing comma is allowed
164//!         }
165//!     }
166//!
167//!     // If this annotation is left off, a variant `Msg(s: String)` will be added, and `From`
168//!     // impls will be provided for `String` and `&str`
169//!     skip_msg_variant
170//! }
171//!
172//! # fn main() {}
173//! ```
174//!
175//! Each section, `types`, `links`, `foreign_links`, and `errors` may
176//! be omitted if it is empty.
177//!
178//! This populates the module with a number of definitions,
179//! the most important of which are the [`Error`] type
180//! and the [`ErrorKind`] type. An example of generated code can be found in the
181//! [example_generated](example_generated/index.html) module.
182//!
183//! ## Returning new errors
184//!
185//! Introducing new error chains, with a string message:
186//!
187//! ```
188//! # #[macro_use] extern crate error_chain;
189//! # fn main() {}
190//! # error_chain! {}
191//! fn foo() -> Result<()> {
192//!     Err("foo error!".into())
193//! }
194//! ```
195//!
196//! Introducing new error chains, with an [`ErrorKind`]:
197//!
198//! ```
199//! # #[macro_use] extern crate error_chain;
200//! # fn main() {}
201//! error_chain! {
202//!     errors { FooError }
203//! }
204//!
205//! fn foo() -> Result<()> {
206//!     Err(ErrorKind::FooError.into())
207//! }
208//! ```
209//!
210//! Note that the return type is the typedef [`Result`], which is
211//! defined by the macro as `pub type Result<T> =
212//! ::std::result::Result<T, Error>`. Note that in both cases
213//! [`.into()`] is called to convert a type into the [`Error`] type; both
214//! strings and [`ErrorKind`] have [`From`] conversions to turn them into
215//! [`Error`].
216//!
217//! When the error is emitted behind the `?` operator, the explicit conversion
218//! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
219//! So the below is equivalent to the previous:
220//!
221//! ```
222//! # #[macro_use] extern crate error_chain;
223//! # fn main() {}
224//! # error_chain! { errors { FooError } }
225//! fn foo() -> Result<()> {
226//!     Ok(Err(ErrorKind::FooError)?)
227//! }
228//!
229//! fn bar() -> Result<()> {
230//!     Ok(Err("bogus!")?)
231//! }
232//! ```
233//!
234//! ## The `bail!` macro
235//!
236//! The above method of introducing new errors works but is a little
237//! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
238//! with conversions done automatically.
239//!
240//! With [`bail!`] the previous examples look like:
241//!
242//! ```
243//! # #[macro_use] extern crate error_chain;
244//! # fn main() {}
245//! # error_chain! { errors { FooError } }
246//! fn foo() -> Result<()> {
247//!     if true {
248//!         bail!(ErrorKind::FooError);
249//!     } else {
250//!         Ok(())
251//!     }
252//! }
253//!
254//! fn bar() -> Result<()> {
255//!     if true {
256//!         bail!("bogus!");
257//!     } else {
258//!         Ok(())
259//!     }
260//! }
261//! ```
262//!
263//! ## Chaining errors
264//! error-chain supports extending an error chain by appending new errors.
265//! This can be done on a Result or on an existing Error.
266//!
267//! To extend the error chain:
268//!
269//! ```
270//! # #[macro_use] extern crate error_chain;
271//! # fn main() {}
272//! # error_chain! {}
273//! # fn do_something() -> Result<()> { unimplemented!() }
274//! # fn test() -> Result<()> {
275//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
276//! # Ok(())
277//! # }
278//! ```
279//!
280//! [`chain_err`] can be called on any [`Result`] type where the contained
281//! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
282//! the [`Result`] type's corresponding [`ResultExt`] trait is in scope.  If
283//! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
284//! which returns *some type that can be converted to [`ErrorKind`]*,
285//! boxes the original error to store as the cause, then returns a new
286//! error containing the original error.
287//!
288//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
289//! the same signature and produces the same outcome as being called on a
290//! [`Result`] matching the properties described above. This is most useful when
291//! partially handling errors using the [`map_err`] function.
292//!
293//! To chain an error directly, use [`with_chain`]:
294//!
295//! ```
296//! # #[macro_use] extern crate error_chain;
297//! # fn main() {}
298//! # error_chain! {}
299//! # fn do_something() -> Result<()> { unimplemented!() }
300//! # fn test() -> Result<()> {
301//! let res: Result<()> =
302//!     do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
303//! # Ok(())
304//! # }
305//! ```
306//!
307//! ## Linking errors
308//!
309//! To convert an error from another error chain to this error chain:
310//!
311//! ```
312//! # #[macro_use] extern crate error_chain;
313//! # fn main() {}
314//! # mod other { error_chain! {} }
315//! error_chain! {
316//!     links {
317//!         OtherError(other::Error, other::ErrorKind);
318//!     }
319//! }
320//!
321//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
322//!
323//! # fn test() -> Result<()> {
324//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
325//! # Ok(())
326//! # }
327//! ```
328//!
329//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
330//! types of all linked error chains. Linked errors do not introduce a new
331//! cause to the error chain.
332//!
333//! ## Matching errors
334//!
335//! error-chain error variants are matched with simple patterns.
336//! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
337//! making dispatching on error kinds relatively compact:
338//!
339//! ```
340//! # #[macro_use] extern crate error_chain;
341//! # fn main() {
342//! error_chain! {
343//!     errors {
344//!         InvalidToolchainName(t: String) {
345//!             description("invalid toolchain name")
346//!             display("invalid toolchain name: '{}'", t)
347//!         }
348//!     }
349//! }
350//!
351//! match Error::from("error!") {
352//!     Error(ErrorKind::InvalidToolchainName(_), _) => { }
353//!     Error(ErrorKind::Msg(_), _) => { }
354//!     _ => { }
355//! }
356//! # }
357//! ```
358//!
359//! Chained errors are also matched with (relatively) compact syntax
360//!
361//! ```
362//! # #[macro_use] extern crate error_chain;
363//! mod utils {
364//!     error_chain! {
365//!         errors {
366//!             BadStuff {
367//!                 description("bad stuff")
368//!             }
369//!         }
370//!     }
371//! }
372//!
373//! mod app {
374//!     error_chain! {
375//!         links {
376//!             Utils(::utils::Error, ::utils::ErrorKind);
377//!         }
378//!     }
379//! }
380//!
381//!
382//! # fn main() {
383//! match app::Error::from("error!") {
384//!     app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
385//!     _ => { }
386//! }
387//! # }
388//! ```
389//!
390//! ## Inspecting errors
391//!
392//! An error-chain error contains information about the error itself, a backtrace, and the chain
393//! of causing errors. For reporting purposes, this information can be accessed as follows.
394//!
395//! ```
396//! # #[macro_use] extern crate error_chain;
397//! use error_chain::ChainedError;  // for e.display_chain()
398//!
399//! error_chain! {
400//!     errors {
401//!         InvalidToolchainName(t: String) {
402//!             description("invalid toolchain name")
403//!             display("invalid toolchain name: '{}'", t)
404//!         }
405//!     }
406//! }
407//!
408//! # fn main() {
409//! // Generate an example error to inspect:
410//! let e = "xyzzy".parse::<i32>()
411//!     .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
412//!     .unwrap_err();
413//!
414//! // Get the brief description of the error:
415//! assert_eq!(e.description(), "invalid toolchain name");
416//!
417//! // Get the display version of the error:
418//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
419//!
420//! // Get the full cause and backtrace:
421//! println!("{}", e.display_chain().to_string());
422//! //     Error: invalid toolchain name: 'xyzzy'
423//! //     Caused by: invalid digit found in string
424//! //     stack backtrace:
425//! //        0:     0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
426//! //                             at src/backtrace/libunwind.rs:53
427//! //                              - backtrace::backtrace::trace<closure>
428//! //                             at src/backtrace/mod.rs:42
429//! //        1:     0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
430//! //                             at out/capture.rs:79
431//! //     [..]
432//! # }
433//! ```
434//!
435//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
436//!
437//! ## Foreign links
438//!
439//! Errors that do not conform to the same conventions as this library
440//! can still be included in the error chain. They are considered "foreign
441//! errors", and are declared using the `foreign_links` block of the
442//! [`error_chain!`] macro. [`Error`]s are automatically created from
443//! foreign errors by the `?` operator.
444//!
445//! Foreign links and regular links have one crucial difference:
446//! [`From`] conversions for regular links *do not introduce a new error
447//! into the error chain*, while conversions for foreign links *always
448//! introduce a new error into the error chain*. So for the example
449//! above all errors deriving from the [`std::fmt::Error`] type will be
450//! presented to the user as a new [`ErrorKind`] variant, and the
451//! cause will be the original [`std::fmt::Error`] error. In contrast, when
452//! `other_error::Error` is converted to `Error` the two `ErrorKind`s
453//! are converted between each other to create a new `Error` but the
454//! old error is discarded; there is no "cause" created from the
455//! original error.
456//!
457//! ## Backtraces
458//!
459//! If the `RUST_BACKTRACE` environment variable is set to anything
460//! but ``0``, the earliest non-foreign error to be generated creates
461//! a single backtrace, which is passed through all [`From`] conversions
462//! and [`chain_err`] invocations of compatible types. To read the
463//! backtrace just call the [`backtrace`] method.
464//!
465//! Backtrace generation can be disabled by turning off the `backtrace` feature.
466//!
467//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
468//! on directly.  For example, to only see the files and line numbers of code
469//! within your own project.
470//!
471//! ```
472//! # #[macro_use]
473//! # extern crate error_chain;
474//! # mod errors {
475//! #   error_chain! {
476//! #       foreign_links {
477//! #           Io(::std::io::Error);
478//! #       }
479//! #   }
480//! # }
481//! # use errors::*;
482//! # #[cfg(feature="backtrace")]
483//! # fn main() {
484//! if let Err(ref e) = open_file() {
485//!     if let Some(backtrace) = e.backtrace() {
486//!         let frames = backtrace.frames();
487//!         for frame in frames.iter() {
488//!             for symbol in frame.symbols().iter() {
489//!                 if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
490//!                     if file.display().to_string()[0..3] == "src".to_string(){
491//!                         println!("{}:{}", file.display().to_string(), lineno);
492//!                     }
493//!                 }
494//!             }
495//!         }
496//!     }
497//! };
498//! # }
499//! # #[cfg(not(feature="backtrace"))]
500//! # fn main() { }
501//!
502//! fn open_file() -> Result<()> {
503//!    std::fs::File::open("does_not_exist")?;
504//!    Ok(())
505//! }
506//! ```
507//!
508//! ## Iteration
509//!
510//! The [`iter`] method returns an iterator over the chain of error boxes.
511//!
512//! [error-type]: https://github.com/DanielKeep/rust-error-type
513//! [quick-error]: https://github.com/tailhook/quick-error
514
515//! [`display_chain`]: trait.ChainedError.html#method.display_chain
516//! [`error_chain!`]: macro.error_chain.html
517//! [`bail!`]: macro.bail.html
518//! [`Backtrace`]: struct.Backtrace.html
519
520//! [`Error`]: example_generated/struct.Error.html
521//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
522//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
523//! [`cause`]: example_generated/struct.Error.html#method.cause
524//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
525//! [`iter`]: example_generated/struct.Error.html#method.iter
526//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
527//! [`description`]: example_generated/enum.ErrorKind.html#method.description
528//! [`Result`]: example_generated/type.Result.html
529//! [`ResultExt`]: example_generated/trait.ResultExt.html
530//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
531
532//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
533//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
534//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
535//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
536//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
537//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
538//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
539//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
540//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
541
542use std::error;
543use std::fmt;
544use std::iter::Iterator;
545
546#[macro_use]
547mod impl_error_chain_kind;
548#[macro_use]
549mod error_chain;
550#[macro_use]
551mod quick_main;
552pub use quick_main::ExitCode;
553mod backtrace;
554#[cfg(feature = "example_generated")]
555pub mod example_generated;
556pub use backtrace::Backtrace;
557#[doc(hidden)]
558pub use backtrace::InternalBacktrace;
559
560#[derive(Debug)]
561#[allow(unknown_lints, bare_trait_objects)]
562/// Iterator over the error chain using the `Error::cause()` method.
563pub struct Iter<'a>(Option<&'a error::Error>);
564
565impl<'a> Iter<'a> {
566    /// Returns a new iterator over the error chain using `Error::cause()`.
567    #[allow(unknown_lints, bare_trait_objects)]
568    pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
569        Iter(err)
570    }
571}
572
573#[allow(unknown_lints, bare_trait_objects)]
574impl<'a> Iterator for Iter<'a> {
575    type Item = &'a error::Error;
576
577    fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
578        match self.0.take() {
579            Some(e) => {
580                self.0 = match () {
581                    #[cfg(not(has_error_source))]
582                    () => e.cause(),
583                    #[cfg(has_error_source)]
584                    () => e.source(),
585                };
586                Some(e)
587            }
588            None => None,
589        }
590    }
591}
592
593/// This trait is implemented on all the errors generated by the `error_chain`
594/// macro.
595pub trait ChainedError: error::Error + Send + 'static {
596    /// Associated kind type.
597    type ErrorKind;
598
599    /// Constructs an error from a kind, and generates a backtrace.
600    fn from_kind(kind: Self::ErrorKind) -> Self
601    where
602        Self: Sized;
603
604    /// Constructs a chained error from another error and a kind, and generates a backtrace.
605    fn with_chain<E, K>(error: E, kind: K) -> Self
606    where
607        Self: Sized,
608        E: ::std::error::Error + Send + 'static,
609        K: Into<Self::ErrorKind>;
610
611    /// Returns the kind of the error.
612    fn kind(&self) -> &Self::ErrorKind;
613
614    /// Iterates over the error chain.
615    fn iter(&self) -> Iter;
616
617    /// Returns the backtrace associated with this error.
618    fn backtrace(&self) -> Option<&Backtrace>;
619
620    /// Returns an object which implements `Display` for printing the full
621    /// context of this error.
622    ///
623    /// The full cause chain and backtrace, if present, will be printed.
624    fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
625        DisplayChain(self)
626    }
627
628    /// Extends the error chain with a new entry.
629    fn chain_err<F, EK>(self, error: F) -> Self
630    where
631        F: FnOnce() -> EK,
632        EK: Into<Self::ErrorKind>;
633
634    /// Creates an error from its parts.
635    #[doc(hidden)]
636    fn new(kind: Self::ErrorKind, state: State) -> Self
637    where
638        Self: Sized;
639
640    /// Returns the first known backtrace, either from its State or from one
641    /// of the errors from `foreign_links`.
642    #[doc(hidden)]
643    #[allow(unknown_lints, bare_trait_objects)]
644    fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
645    where
646        Self: Sized;
647}
648
649/// A struct which formats an error for output.
650#[derive(Debug)]
651pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
652
653impl<'a, T> fmt::Display for DisplayChain<'a, T>
654where
655    T: ChainedError,
656{
657    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
658        writeln!(fmt, "Error: {}", self.0)?;
659
660        for e in self.0.iter().skip(1) {
661            writeln!(fmt, "Caused by: {}", e)?;
662        }
663
664        if let Some(backtrace) = ChainedError::backtrace(self.0) {
665            writeln!(fmt, "{:?}", backtrace)?;
666        }
667
668        Ok(())
669    }
670}
671
672/// Common state between errors.
673#[derive(Debug)]
674#[doc(hidden)]
675#[allow(unknown_lints, bare_trait_objects)]
676pub struct State {
677    /// Next error in the error chain.
678    pub next_error: Option<Box<error::Error + Send>>,
679    /// Backtrace for the current error.
680    pub backtrace: InternalBacktrace,
681}
682
683impl Default for State {
684    fn default() -> State {
685        State {
686            next_error: None,
687            backtrace: InternalBacktrace::new(),
688        }
689    }
690}
691
692impl State {
693    /// Creates a new State type
694    #[allow(unknown_lints, bare_trait_objects)]
695    pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
696        let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
697        State {
698            next_error: Some(e),
699            backtrace: backtrace,
700        }
701    }
702
703    /// Returns the inner backtrace if present.
704    pub fn backtrace(&self) -> Option<&Backtrace> {
705        self.backtrace.as_backtrace()
706    }
707}
708
709/// Exits a function early with an error
710///
711/// The `bail!` macro provides an easy way to exit a function.
712/// `bail!(expr)` is equivalent to writing.
713///
714/// ```
715/// # #[macro_use] extern crate error_chain;
716/// # error_chain! { }
717/// # fn main() { }
718/// # fn foo() -> Result<()> {
719/// # let expr = "";
720///     return Err(expr.into());
721/// # }
722/// ```
723///
724/// And as shorthand it takes a formatting string a la `println!`:
725///
726/// ```
727/// # #[macro_use] extern crate error_chain;
728/// # error_chain! { }
729/// # fn main() { }
730/// # fn foo() -> Result<()> {
731/// # let n = 0;
732/// bail!("bad number: {}", n);
733/// # }
734/// ```
735///
736/// # Examples
737///
738/// Bailing on a custom error:
739///
740/// ```
741/// # #[macro_use] extern crate error_chain;
742/// # fn main() {}
743/// error_chain! {
744///     errors { FooError }
745/// }
746///
747/// fn foo() -> Result<()> {
748///     if bad_condition() {
749///         bail!(ErrorKind::FooError);
750///     }
751///
752///     Ok(())
753/// }
754///
755/// # fn bad_condition() -> bool { true }
756/// ```
757///
758/// Bailing on a formatted string:
759///
760/// ```
761/// # #[macro_use] extern crate error_chain;
762/// # fn main() {}
763/// error_chain! { }
764///
765/// fn foo() -> Result<()> {
766///     if let Some(bad_num) = bad_condition() {
767///         bail!("so bad: {}", bad_num);
768///     }
769///
770///     Ok(())
771/// }
772///
773/// # fn bad_condition() -> Option<i8> { None }
774/// ```
775#[macro_export]
776macro_rules! bail {
777    ($e:expr) => {
778        return Err($e.into());
779    };
780    ($fmt:expr, $($arg:tt)+) => {
781        return Err(format!($fmt, $($arg)+).into());
782    };
783}
784
785/// Exits a function early with an error if the condition is not satisfied
786///
787/// The `ensure!` macro is a convenience helper that provides a way to exit
788/// a function with an error if the given condition fails.
789///
790/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
791///
792/// ```
793/// # #[macro_use] extern crate error_chain;
794/// # error_chain! { }
795/// # fn main() { }
796/// # fn foo() -> Result<()> {
797/// # let errcode = 0u8;
798/// # let condition = true;
799/// if !condition {
800///     bail!("error code: {}", errcode);
801/// }
802/// # Ok(())
803/// # }
804/// ```
805///
806/// See documentation for `bail!` macro for further details.
807#[macro_export(local_inner_macros)]
808macro_rules! ensure {
809    ($cond:expr, $e:expr) => {
810        if !($cond) {
811            bail!($e);
812        }
813    };
814    ($cond:expr, $fmt:expr, $($arg:tt)+) => {
815        if !($cond) {
816            bail!($fmt, $($arg)+);
817        }
818    };
819}
820
821#[doc(hidden)]
822pub mod mock {
823    error_chain! {}
824}