Coverage Report

Created: 2025-12-12 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/error-chain-0.12.4/src/lib.rs
Line
Count
Source
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
542
use std::error;
543
use std::fmt;
544
use std::iter::Iterator;
545
546
#[macro_use]
547
mod impl_error_chain_kind;
548
#[macro_use]
549
mod error_chain;
550
#[macro_use]
551
mod quick_main;
552
pub use quick_main::ExitCode;
553
mod backtrace;
554
#[cfg(feature = "example_generated")]
555
pub mod example_generated;
556
pub use backtrace::Backtrace;
557
#[doc(hidden)]
558
pub 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.
563
pub struct Iter<'a>(Option<&'a error::Error>);
564
565
impl<'a> Iter<'a> {
566
    /// Returns a new iterator over the error chain using `Error::cause()`.
567
    #[allow(unknown_lints, bare_trait_objects)]
568
0
    pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
569
0
        Iter(err)
570
0
    }
571
}
572
573
#[allow(unknown_lints, bare_trait_objects)]
574
impl<'a> Iterator for Iter<'a> {
575
    type Item = &'a error::Error;
576
577
0
    fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
578
0
        match self.0.take() {
579
0
            Some(e) => {
580
0
                self.0 = match () {
581
0
                    #[cfg(not(has_error_source))]
582
0
                    () => e.cause(),
583
0
                    #[cfg(has_error_source)]
584
0
                    () => e.source(),
585
0
                };
586
0
                Some(e)
587
            }
588
0
            None => None,
589
        }
590
0
    }
591
}
592
593
/// This trait is implemented on all the errors generated by the `error_chain`
594
/// macro.
595
pub 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
0
    fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
625
0
        DisplayChain(self)
626
0
    }
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)]
651
pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
652
653
impl<'a, T> fmt::Display for DisplayChain<'a, T>
654
where
655
    T: ChainedError,
656
{
657
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
658
0
        writeln!(fmt, "Error: {}", self.0)?;
659
660
0
        for e in self.0.iter().skip(1) {
661
0
            writeln!(fmt, "Caused by: {}", e)?;
662
        }
663
664
0
        if let Some(backtrace) = ChainedError::backtrace(self.0) {
665
0
            writeln!(fmt, "{:?}", backtrace)?;
666
0
        }
667
668
0
        Ok(())
669
0
    }
670
}
671
672
/// Common state between errors.
673
#[derive(Debug)]
674
#[doc(hidden)]
675
#[allow(unknown_lints, bare_trait_objects)]
676
pub 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
683
impl Default for State {
684
0
    fn default() -> State {
685
0
        State {
686
0
            next_error: None,
687
0
            backtrace: InternalBacktrace::new(),
688
0
        }
689
0
    }
690
}
691
692
impl State {
693
    /// Creates a new State type
694
    #[allow(unknown_lints, bare_trait_objects)]
695
0
    pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
696
0
        let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
697
0
        State {
698
0
            next_error: Some(e),
699
0
            backtrace: backtrace,
700
0
        }
701
0
    }
Unexecuted instantiation: <error_chain::State>::new::<syslog::errors::Error>
Unexecuted instantiation: <error_chain::State>::new::<_>
Unexecuted instantiation: <error_chain::State>::new::<syslog::errors::Error>
702
703
    /// Returns the inner backtrace if present.
704
0
    pub fn backtrace(&self) -> Option<&Backtrace> {
705
0
        self.backtrace.as_backtrace()
706
0
    }
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]
776
macro_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)]
808
macro_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)]
822
pub mod mock {
823
    error_chain! {}
824
}