error_chain/
lib.rs

1#![deny(missing_docs)]
2#![doc(html_root_url = "https://docs.rs/error-chain/0.12.0")]
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//!
168//! # fn main() {}
169//! ```
170//!
171//! Each section, `types`, `links`, `foreign_links`, and `errors` may
172//! be omitted if it is empty.
173//!
174//! This populates the module with a number of definitions,
175//! the most important of which are the [`Error`] type
176//! and the [`ErrorKind`] type. An example of generated code can be found in the
177//! [example_generated](example_generated/index.html) module.
178//!
179//! ## Returning new errors
180//!
181//! Introducing new error chains, with a string message:
182//!
183//! ```
184//! # #[macro_use] extern crate error_chain;
185//! # fn main() {}
186//! # error_chain! {}
187//! fn foo() -> Result<()> {
188//!     Err("foo error!".into())
189//! }
190//! ```
191//!
192//! Introducing new error chains, with an [`ErrorKind`]:
193//!
194//! ```
195//! # #[macro_use] extern crate error_chain;
196//! # fn main() {}
197//! error_chain! {
198//!     errors { FooError }
199//! }
200//!
201//! fn foo() -> Result<()> {
202//!     Err(ErrorKind::FooError.into())
203//! }
204//! ```
205//!
206//! Note that the return type is the typedef [`Result`], which is
207//! defined by the macro as `pub type Result<T> =
208//! ::std::result::Result<T, Error>`. Note that in both cases
209//! [`.into()`] is called to convert a type into the [`Error`] type; both
210//! strings and [`ErrorKind`] have [`From`] conversions to turn them into
211//! [`Error`].
212//!
213//! When the error is emitted behind the `?` operator, the explicit conversion
214//! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
215//! So the below is equivalent to the previous:
216//!
217//! ```
218//! # #[macro_use] extern crate error_chain;
219//! # fn main() {}
220//! # error_chain! { errors { FooError } }
221//! fn foo() -> Result<()> {
222//!     Ok(Err(ErrorKind::FooError)?)
223//! }
224//!
225//! fn bar() -> Result<()> {
226//!     Ok(Err("bogus!")?)
227//! }
228//! ```
229//!
230//! ## The `bail!` macro
231//!
232//! The above method of introducing new errors works but is a little
233//! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
234//! with conversions done automatically.
235//!
236//! With [`bail!`] the previous examples look like:
237//!
238//! ```
239//! # #[macro_use] extern crate error_chain;
240//! # fn main() {}
241//! # error_chain! { errors { FooError } }
242//! fn foo() -> Result<()> {
243//!     if true {
244//!         bail!(ErrorKind::FooError);
245//!     } else {
246//!         Ok(())
247//!     }
248//! }
249//!
250//! fn bar() -> Result<()> {
251//!     if true {
252//!         bail!("bogus!");
253//!     } else {
254//!         Ok(())
255//!     }
256//! }
257//! ```
258//!
259//! ## Chaining errors
260//! error-chain supports extending an error chain by appending new errors.
261//! This can be done on a Result or on an existing Error.
262//!
263//! To extend the error chain:
264//!
265//! ```
266//! # #[macro_use] extern crate error_chain;
267//! # fn main() {}
268//! # error_chain! {}
269//! # fn do_something() -> Result<()> { unimplemented!() }
270//! # fn test() -> Result<()> {
271//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
272//! # Ok(())
273//! # }
274//! ```
275//!
276//! [`chain_err`] can be called on any [`Result`] type where the contained
277//! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
278//! the [`Result`] type's corresponding [`ResultExt`] trait is in scope.  If
279//! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
280//! which returns *some type that can be converted to [`ErrorKind`]*,
281//! boxes the original error to store as the cause, then returns a new
282//! error containing the original error.
283//!
284//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
285//! the same signature and produces the same outcome as being called on a
286//! [`Result`] matching the properties described above. This is most useful when
287//! partially handling errors using the [`map_err`] function.
288//!
289//! To chain an error directly, use [`with_chain`]:
290//!
291//! ```
292//! # #[macro_use] extern crate error_chain;
293//! # fn main() {}
294//! # error_chain! {}
295//! # fn do_something() -> Result<()> { unimplemented!() }
296//! # fn test() -> Result<()> {
297//! let res: Result<()> =
298//!     do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
299//! # Ok(())
300//! # }
301//! ```
302//!
303//! ## Linking errors
304//!
305//! To convert an error from another error chain to this error chain:
306//!
307//! ```
308//! # #[macro_use] extern crate error_chain;
309//! # fn main() {}
310//! # mod other { error_chain! {} }
311//! error_chain! {
312//!     links {
313//!         OtherError(other::Error, other::ErrorKind);
314//!     }
315//! }
316//!
317//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
318//!
319//! # fn test() -> Result<()> {
320//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
321//! # Ok(())
322//! # }
323//! ```
324//!
325//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
326//! types of all linked error chains. Linked errors do not introduce a new
327//! cause to the error chain.
328//!
329//! ## Matching errors
330//!
331//! error-chain error variants are matched with simple patterns.
332//! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
333//! making dispatching on error kinds relatively compact:
334//!
335//! ```
336//! # #[macro_use] extern crate error_chain;
337//! # fn main() {
338//! error_chain! {
339//!     errors {
340//!         InvalidToolchainName(t: String) {
341//!             description("invalid toolchain name")
342//!             display("invalid toolchain name: '{}'", t)
343//!         }
344//!     }
345//! }
346//!
347//! match Error::from("error!") {
348//!     Error(ErrorKind::InvalidToolchainName(_), _) => { }
349//!     Error(ErrorKind::Msg(_), _) => { }
350//!     _ => { }
351//! }
352//! # }
353//! ```
354//!
355//! Chained errors are also matched with (relatively) compact syntax
356//!
357//! ```
358//! # #[macro_use] extern crate error_chain;
359//! mod utils {
360//!     error_chain! {
361//!         errors {
362//!             BadStuff {
363//!                 description("bad stuff")
364//!             }
365//!         }
366//!     }
367//! }
368//!
369//! mod app {
370//!     error_chain! {
371//!         links {
372//!             Utils(::utils::Error, ::utils::ErrorKind);
373//!         }
374//!     }
375//! }
376//!
377//!
378//! # fn main() {
379//! match app::Error::from("error!") {
380//!     app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
381//!     _ => { }
382//! }
383//! # }
384//! ```
385//!
386//! ## Inspecting errors
387//!
388//! An error-chain error contains information about the error itself, a backtrace, and the chain
389//! of causing errors. For reporting purposes, this information can be accessed as follows.
390//!
391//! ```
392//! # #[macro_use] extern crate error_chain;
393//! use error_chain::ChainedError;  // for e.display_chain()
394//!
395//! error_chain! {
396//!     errors {
397//!         InvalidToolchainName(t: String) {
398//!             description("invalid toolchain name")
399//!             display("invalid toolchain name: '{}'", t)
400//!         }
401//!     }
402//! }
403//!
404//! # fn main() {
405//! // Generate an example error to inspect:
406//! let e = "xyzzy".parse::<i32>()
407//!     .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
408//!     .unwrap_err();
409//!
410//! // Get the brief description of the error:
411//! assert_eq!(e.description(), "invalid toolchain name");
412//!
413//! // Get the display version of the error:
414//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
415//!
416//! // Get the full cause and backtrace:
417//! println!("{}", e.display_chain().to_string());
418//! //     Error: invalid toolchain name: 'xyzzy'
419//! //     Caused by: invalid digit found in string
420//! //     stack backtrace:
421//! //        0:     0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
422//! //                             at src/backtrace/libunwind.rs:53
423//! //                              - backtrace::backtrace::trace<closure>
424//! //                             at src/backtrace/mod.rs:42
425//! //        1:     0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
426//! //                             at out/capture.rs:79
427//! //     [..]
428//! # }
429//! ```
430//!
431//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
432//!
433//! ## Foreign links
434//!
435//! Errors that do not conform to the same conventions as this library
436//! can still be included in the error chain. They are considered "foreign
437//! errors", and are declared using the `foreign_links` block of the
438//! [`error_chain!`] macro. [`Error`]s are automatically created from
439//! foreign errors by the `?` operator.
440//!
441//! Foreign links and regular links have one crucial difference:
442//! [`From`] conversions for regular links *do not introduce a new error
443//! into the error chain*, while conversions for foreign links *always
444//! introduce a new error into the error chain*. So for the example
445//! above all errors deriving from the [`std::fmt::Error`] type will be
446//! presented to the user as a new [`ErrorKind`] variant, and the
447//! cause will be the original [`std::fmt::Error`] error. In contrast, when
448//! `other_error::Error` is converted to `Error` the two `ErrorKind`s
449//! are converted between each other to create a new `Error` but the
450//! old error is discarded; there is no "cause" created from the
451//! original error.
452//!
453//! ## Backtraces
454//!
455//! If the `RUST_BACKTRACE` environment variable is set to anything
456//! but ``0``, the earliest non-foreign error to be generated creates
457//! a single backtrace, which is passed through all [`From`] conversions
458//! and [`chain_err`] invocations of compatible types. To read the
459//! backtrace just call the [`backtrace`] method.
460//!
461//! Backtrace generation can be disabled by turning off the `backtrace` feature.
462//!
463//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
464//! on directly.  For example, to only see the files and line numbers of code
465//! within your own project.
466//!
467//! ```
468//! # #[macro_use]
469//! # extern crate error_chain;
470//! # mod errors {
471//! #   error_chain! {
472//! #       foreign_links {
473//! #           Io(::std::io::Error);
474//! #       }
475//! #   }
476//! # }
477//! # use errors::*;
478//! # #[cfg(feature="backtrace")]
479//! # fn main() {
480//! if let Err(ref e) = open_file() {
481//!     if let Some(backtrace) = e.backtrace() {
482//!         let frames = backtrace.frames();
483//!         for frame in frames.iter() {
484//!             for symbol in frame.symbols().iter() {
485//!                 if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
486//!                     if file.display().to_string()[0..3] == "src".to_string(){
487//!                         println!("{}:{}", file.display().to_string(), lineno);
488//!                     }
489//!                 }
490//!             }
491//!         }
492//!     }
493//! };
494//! # }
495//! # #[cfg(not(feature="backtrace"))]
496//! # fn main() { }
497//!
498//! fn open_file() -> Result<()> {
499//!    std::fs::File::open("does_not_exist")?;
500//!    Ok(())
501//! }
502//! ```
503//!
504//! ## Iteration
505//!
506//! The [`iter`] method returns an iterator over the chain of error boxes.
507//!
508//! [error-type]: https://github.com/DanielKeep/rust-error-type
509//! [quick-error]: https://github.com/tailhook/quick-error
510
511//! [`display_chain`]: trait.ChainedError.html#method.display_chain
512//! [`error_chain!`]: macro.error_chain.html
513//! [`bail!`]: macro.bail.html
514//! [`Backtrace`]: struct.Backtrace.html
515
516//! [`Error`]: example_generated/struct.Error.html
517//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
518//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
519//! [`cause`]: example_generated/struct.Error.html#method.cause
520//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
521//! [`iter`]: example_generated/struct.Error.html#method.iter
522//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
523//! [`description`]: example_generated/enum.ErrorKind.html#method.description
524//! [`Result`]: example_generated/type.Result.html
525//! [`ResultExt`]: example_generated/trait.ResultExt.html
526//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
527
528//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
529//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
530//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
531//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
532//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
533//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
534//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
535//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
536//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
537
538use std::error;
539use std::iter::Iterator;
540use std::fmt;
541
542#[macro_use]
543mod impl_error_chain_kind;
544#[macro_use]
545mod error_chain;
546#[macro_use]
547mod quick_main;
548pub use quick_main::ExitCode;
549#[cfg(feature = "example_generated")]
550pub mod example_generated;
551mod backtrace;
552pub use backtrace::Backtrace;
553#[doc(hidden)]
554pub use backtrace::InternalBacktrace;
555
556#[derive(Debug)]
557/// Iterator over the error chain using the `Error::cause()` method.
558pub struct Iter<'a>(Option<&'a error::Error>);
559
560impl<'a> Iter<'a> {
561    /// Returns a new iterator over the error chain using `Error::cause()`.
562    pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
563        Iter(err)
564    }
565}
566
567impl<'a> Iterator for Iter<'a> {
568    type Item = &'a error::Error;
569
570    fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
571        match self.0.take() {
572            Some(e) => {
573                self.0 = e.cause();
574                Some(e)
575            }
576            None => None,
577        }
578    }
579}
580
581/// This trait is implemented on all the errors generated by the `error_chain`
582/// macro.
583pub trait ChainedError: error::Error + Send + 'static {
584    /// Associated kind type.
585    type ErrorKind;
586
587    /// Constructs an error from a kind, and generates a backtrace.
588    fn from_kind(kind: Self::ErrorKind) -> Self where Self: Sized;
589
590    /// Constructs a chained error from another error and a kind, and generates a backtrace.
591    fn with_chain<E, K>(error: E, kind: K) -> Self
592        where Self: Sized,
593              E: ::std::error::Error + Send + 'static,
594              K: Into<Self::ErrorKind>;
595
596    /// Returns the kind of the error.
597    fn kind(&self) -> &Self::ErrorKind;
598
599    /// Iterates over the error chain.
600    fn iter(&self) -> Iter;
601
602    /// Returns the backtrace associated with this error.
603    fn backtrace(&self) -> Option<&Backtrace>;
604
605    /// Returns an object which implements `Display` for printing the full
606    /// context of this error.
607    ///
608    /// The full cause chain and backtrace, if present, will be printed.
609    fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
610        DisplayChain(self)
611    }
612
613    /// Extends the error chain with a new entry.
614    fn chain_err<F, EK>(self, error: F) -> Self
615        where F: FnOnce() -> EK,
616              EK: Into<Self::ErrorKind>;
617
618    /// Creates an error from its parts.
619    #[doc(hidden)]
620    fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized;
621
622    /// Returns the first known backtrace, either from its State or from one
623    /// of the errors from `foreign_links`.
624    #[doc(hidden)]
625    fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
626        where Self: Sized;
627}
628
629/// A struct which formats an error for output.
630#[derive(Debug)]
631pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
632
633impl<'a, T> fmt::Display for DisplayChain<'a, T>
634    where T: ChainedError
635{
636    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
637        // Keep `try!` for 1.10 support
638        try!(writeln!(fmt, "Error: {}", self.0));
639
640        for e in self.0.iter().skip(1) {
641            try!(writeln!(fmt, "Caused by: {}", e));
642        }
643
644        if let Some(backtrace) = self.0.backtrace() {
645            try!(writeln!(fmt, "{:?}", backtrace));
646        }
647
648        Ok(())
649    }
650}
651
652/// Common state between errors.
653#[derive(Debug)]
654#[doc(hidden)]
655pub struct State {
656    /// Next error in the error chain.
657    pub next_error: Option<Box<error::Error + Send>>,
658    /// Backtrace for the current error.
659    pub backtrace: InternalBacktrace,
660}
661
662impl Default for State {
663    fn default() -> State {
664        State {
665            next_error: None,
666            backtrace: InternalBacktrace::new(),
667        }
668    }
669}
670
671impl State {
672    /// Creates a new State type
673    pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
674        let backtrace = CE::extract_backtrace(&*e)
675            .unwrap_or_else(InternalBacktrace::new);
676        State {
677            next_error: Some(e),
678            backtrace: backtrace,
679        }
680    }
681
682    /// Returns the inner backtrace if present.
683    pub fn backtrace(&self) -> Option<&Backtrace> {
684        self.backtrace.as_backtrace()
685    }
686}
687
688/// Exits a function early with an error
689///
690/// The `bail!` macro provides an easy way to exit a function.
691/// `bail!(expr)` is equivalent to writing.
692///
693/// ```
694/// # #[macro_use] extern crate error_chain;
695/// # error_chain! { }
696/// # fn main() { }
697/// # fn foo() -> Result<()> {
698/// # let expr = "";
699///     return Err(expr.into());
700/// # }
701/// ```
702///
703/// And as shorthand it takes a formatting string a la `println!`:
704///
705/// ```
706/// # #[macro_use] extern crate error_chain;
707/// # error_chain! { }
708/// # fn main() { }
709/// # fn foo() -> Result<()> {
710/// # let n = 0;
711/// bail!("bad number: {}", n);
712/// # }
713/// ```
714///
715/// # Examples
716///
717/// Bailing on a custom error:
718///
719/// ```
720/// # #[macro_use] extern crate error_chain;
721/// # fn main() {}
722/// error_chain! {
723///     errors { FooError }
724/// }
725///
726/// fn foo() -> Result<()> {
727///     if bad_condition() {
728///         bail!(ErrorKind::FooError);
729///     }
730///
731///     Ok(())
732/// }
733///
734/// # fn bad_condition() -> bool { true }
735/// ```
736///
737/// Bailing on a formatted string:
738///
739/// ```
740/// # #[macro_use] extern crate error_chain;
741/// # fn main() {}
742/// error_chain! { }
743///
744/// fn foo() -> Result<()> {
745///     if let Some(bad_num) = bad_condition() {
746///         bail!("so bad: {}", bad_num);
747///     }
748///
749///     Ok(())
750/// }
751///
752/// # fn bad_condition() -> Option<i8> { None }
753/// ```
754#[macro_export]
755macro_rules! bail {
756    ($e:expr) => {
757        return Err($e.into());
758    };
759    ($fmt:expr, $($arg:tt)+) => {
760        return Err(format!($fmt, $($arg)+).into());
761    };
762}
763
764/// Exits a function early with an error if the condition is not satisfied
765///
766/// The `ensure!` macro is a convenience helper that provides a way to exit
767/// a function with an error if the given condition fails.
768///
769/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
770///
771/// ```
772/// # #[macro_use] extern crate error_chain;
773/// # error_chain! { }
774/// # fn main() { }
775/// # fn foo() -> Result<()> {
776/// # let errcode = 0u8;
777/// # let condition = true;
778/// if !condition {
779///     bail!("error code: {}", errcode);
780/// }
781/// # Ok(())
782/// # }
783/// ```
784///
785/// See documentation for `bail!` macro for further details.
786#[macro_export]
787macro_rules! ensure {
788    ($cond:expr, $e:expr) => {
789        if !($cond) {
790            bail!($e);
791        }
792    };
793    ($cond:expr, $fmt:expr, $($arg:tt)+) => {
794        if !($cond) {
795            bail!($fmt, $($arg)+);
796        }
797    };
798}
799
800#[doc(hidden)]
801pub mod mock {
802    error_chain!{}
803}