Coverage Report

Created: 2026-08-14 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.75/src/lib.rs
Line
Count
Source
1
//! [![github]](https://github.com/dtolnay/anyhow) [![crates-io]](https://crates.io/crates/anyhow) [![docs-rs]](https://docs.rs/anyhow)
2
//!
3
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6
//!
7
//! <br>
8
//!
9
//! This library provides [`anyhow::Error`][Error], a trait object based error
10
//! type for easy idiomatic error handling in Rust applications.
11
//!
12
//! <br>
13
//!
14
//! # Details
15
//!
16
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
17
//!   the return type of any fallible function.
18
//!
19
//!   Within the function, use `?` to easily propagate any error that implements
20
//!   the `std::error::Error` trait.
21
//!
22
//!   ```
23
//!   # pub trait Deserialize {}
24
//!   #
25
//!   # mod serde_json {
26
//!   #     use super::Deserialize;
27
//!   #     use std::io;
28
//!   #
29
//!   #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
30
//!   #         unimplemented!()
31
//!   #     }
32
//!   # }
33
//!   #
34
//!   # struct ClusterMap;
35
//!   #
36
//!   # impl Deserialize for ClusterMap {}
37
//!   #
38
//!   use anyhow::Result;
39
//!
40
//!   fn get_cluster_info() -> Result<ClusterMap> {
41
//!       let config = std::fs::read_to_string("cluster.json")?;
42
//!       let map: ClusterMap = serde_json::from_str(&config)?;
43
//!       Ok(map)
44
//!   }
45
//!   #
46
//!   # fn main() {}
47
//!   ```
48
//!
49
//! - Attach context to help the person troubleshooting the error understand
50
//!   where things went wrong. A low-level error like "No such file or
51
//!   directory" can be annoying to debug without more context about what higher
52
//!   level step the application was in the middle of.
53
//!
54
//!   ```
55
//!   # struct It;
56
//!   #
57
//!   # impl It {
58
//!   #     fn detach(&self) -> Result<()> {
59
//!   #         unimplemented!()
60
//!   #     }
61
//!   # }
62
//!   #
63
//!   use anyhow::{Context, Result};
64
//!
65
//!   fn main() -> Result<()> {
66
//!       # return Ok(());
67
//!       #
68
//!       # const _: &str = stringify! {
69
//!       ...
70
//!       # };
71
//!       #
72
//!       # let it = It;
73
//!       # let path = "./path/to/instrs.json";
74
//!       #
75
//!       it.detach().context("Failed to detach the important thing")?;
76
//!
77
//!       let content = std::fs::read(path)
78
//!           .with_context(|| format!("Failed to read instrs from {}", path))?;
79
//!       #
80
//!       # const _: &str = stringify! {
81
//!       ...
82
//!       # };
83
//!       #
84
//!       # Ok(())
85
//!   }
86
//!   ```
87
//!
88
//!   ```console
89
//!   Error: Failed to read instrs from ./path/to/instrs.json
90
//!
91
//!   Caused by:
92
//!       No such file or directory (os error 2)
93
//!   ```
94
//!
95
//! - Downcasting is supported and can be by value, by shared reference, or by
96
//!   mutable reference as needed.
97
//!
98
//!   ```
99
//!   # use anyhow::anyhow;
100
//!   # use std::fmt::{self, Display};
101
//!   # use std::task::Poll;
102
//!   #
103
//!   # #[derive(Debug)]
104
//!   # enum DataStoreError {
105
//!   #     Censored(()),
106
//!   # }
107
//!   #
108
//!   # impl Display for DataStoreError {
109
//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
110
//!   #         unimplemented!()
111
//!   #     }
112
//!   # }
113
//!   #
114
//!   # impl std::error::Error for DataStoreError {}
115
//!   #
116
//!   # const REDACTED_CONTENT: () = ();
117
//!   #
118
//!   # let error = anyhow!("...");
119
//!   # let root_cause = &error;
120
//!   #
121
//!   # let ret =
122
//!   // If the error was caused by redaction, then return a
123
//!   // tombstone instead of the content.
124
//!   match root_cause.downcast_ref::<DataStoreError>() {
125
//!       Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
126
//!       None => Err(error),
127
//!   }
128
//!   # ;
129
//!   ```
130
//!
131
//! - If using the nightly channel, or stable with `features = ["backtrace"]`, a
132
//!   backtrace is captured and printed with the error if the underlying error
133
//!   type does not already provide its own. In order to see backtraces, they
134
//!   must be enabled through the environment variables described in
135
//!   [`std::backtrace`]:
136
//!
137
//!   - If you want panics and errors to both have backtraces, set
138
//!     `RUST_BACKTRACE=1`;
139
//!   - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
140
//!   - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
141
//!     `RUST_LIB_BACKTRACE=0`.
142
//!
143
//!   The tracking issue for this feature is [rust-lang/rust#53487].
144
//!
145
//!   [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
146
//!   [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
147
//!
148
//! - Anyhow works with any error type that has an impl of `std::error::Error`,
149
//!   including ones defined in your crate. We do not bundle a `derive(Error)`
150
//!   macro but you can write the impls yourself or use a standalone macro like
151
//!   [thiserror].
152
//!
153
//!   [thiserror]: https://github.com/dtolnay/thiserror
154
//!
155
//!   ```
156
//!   use thiserror::Error;
157
//!
158
//!   #[derive(Error, Debug)]
159
//!   pub enum FormatError {
160
//!       #[error("Invalid header (expected {expected:?}, got {found:?})")]
161
//!       InvalidHeader {
162
//!           expected: String,
163
//!           found: String,
164
//!       },
165
//!       #[error("Missing attribute: {0}")]
166
//!       MissingAttribute(String),
167
//!   }
168
//!   ```
169
//!
170
//! - One-off error messages can be constructed using the `anyhow!` macro, which
171
//!   supports string interpolation and produces an `anyhow::Error`.
172
//!
173
//!   ```
174
//!   # use anyhow::{anyhow, Result};
175
//!   #
176
//!   # fn demo() -> Result<()> {
177
//!   #     let missing = "...";
178
//!   return Err(anyhow!("Missing attribute: {}", missing));
179
//!   #     Ok(())
180
//!   # }
181
//!   ```
182
//!
183
//!   A `bail!` macro is provided as a shorthand for the same early return.
184
//!
185
//!   ```
186
//!   # use anyhow::{bail, Result};
187
//!   #
188
//!   # fn demo() -> Result<()> {
189
//!   #     let missing = "...";
190
//!   bail!("Missing attribute: {}", missing);
191
//!   #     Ok(())
192
//!   # }
193
//!   ```
194
//!
195
//! <br>
196
//!
197
//! # No-std support
198
//!
199
//! In no_std mode, the same API is almost all available and works the same way.
200
//! To depend on Anyhow in no_std mode, disable our default enabled "std"
201
//! feature in Cargo.toml. A global allocator is required.
202
//!
203
//! ```toml
204
//! [dependencies]
205
//! anyhow = { version = "1.0", default-features = false }
206
//! ```
207
//!
208
//! Since the `?`-based error conversions would normally rely on the
209
//! `std::error::Error` trait which is only available through std, no_std mode
210
//! will require an explicit `.map_err(Error::msg)` when working with a
211
//! non-Anyhow error type inside a function that returns Anyhow's error type.
212
213
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.75")]
214
#![cfg_attr(backtrace, feature(error_generic_member_access))]
215
#![cfg_attr(doc_cfg, feature(doc_cfg))]
216
#![cfg_attr(not(feature = "std"), no_std)]
217
#![deny(dead_code, unused_imports, unused_mut)]
218
#![allow(
219
    clippy::doc_markdown,
220
    clippy::enum_glob_use,
221
    clippy::explicit_auto_deref,
222
    clippy::extra_unused_type_parameters,
223
    clippy::let_underscore_untyped,
224
    clippy::missing_errors_doc,
225
    clippy::missing_panics_doc,
226
    clippy::module_name_repetitions,
227
    clippy::must_use_candidate,
228
    clippy::needless_doctest_main,
229
    clippy::new_ret_no_self,
230
    clippy::redundant_else,
231
    clippy::return_self_not_must_use,
232
    clippy::unused_self,
233
    clippy::used_underscore_binding,
234
    clippy::wildcard_imports,
235
    clippy::wrong_self_convention
236
)]
237
238
extern crate alloc;
239
240
#[macro_use]
241
mod backtrace;
242
mod chain;
243
mod context;
244
mod ensure;
245
mod error;
246
mod fmt;
247
mod kind;
248
mod macros;
249
mod ptr;
250
mod wrapper;
251
252
use crate::error::ErrorImpl;
253
use crate::ptr::Own;
254
use core::fmt::Display;
255
256
#[cfg(not(feature = "std"))]
257
use core::fmt::Debug;
258
259
#[cfg(feature = "std")]
260
use std::error::Error as StdError;
261
262
#[cfg(not(feature = "std"))]
263
trait StdError: Debug + Display {
264
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
265
        None
266
    }
267
}
268
269
#[doc(no_inline)]
270
pub use anyhow as format_err;
271
272
/// The `Error` type, a wrapper around a dynamic error type.
273
///
274
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
275
/// differences:
276
///
277
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
278
/// - `Error` guarantees that a backtrace is available, even if the underlying
279
///   error type does not provide one.
280
/// - `Error` is represented as a narrow pointer &mdash; exactly one word in
281
///   size instead of two.
282
///
283
/// <br>
284
///
285
/// # Display representations
286
///
287
/// When you print an error object using "{}" or to_string(), only the outermost
288
/// underlying error or context is printed, not any of the lower level causes.
289
/// This is exactly as if you had called the Display impl of the error from
290
/// which you constructed your anyhow::Error.
291
///
292
/// ```console
293
/// Failed to read instrs from ./path/to/instrs.json
294
/// ```
295
///
296
/// To print causes as well using anyhow's default formatting of causes, use the
297
/// alternate selector "{:#}".
298
///
299
/// ```console
300
/// Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2)
301
/// ```
302
///
303
/// The Debug format "{:?}" includes your backtrace if one was captured. Note
304
/// that this is the representation you get by default if you return an error
305
/// from `fn main` instead of printing it explicitly yourself.
306
///
307
/// ```console
308
/// Error: Failed to read instrs from ./path/to/instrs.json
309
///
310
/// Caused by:
311
///     No such file or directory (os error 2)
312
/// ```
313
///
314
/// and if there is a backtrace available:
315
///
316
/// ```console
317
/// Error: Failed to read instrs from ./path/to/instrs.json
318
///
319
/// Caused by:
320
///     No such file or directory (os error 2)
321
///
322
/// Stack backtrace:
323
///    0: <E as anyhow::context::ext::StdError>::ext_context
324
///              at /git/anyhow/src/backtrace.rs:26
325
///    1: core::result::Result<T,E>::map_err
326
///              at /git/rustc/src/libcore/result.rs:596
327
///    2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
328
///              at /git/anyhow/src/context.rs:58
329
///    3: testing::main
330
///              at src/main.rs:5
331
///    4: std::rt::lang_start
332
///              at /git/rustc/src/libstd/rt.rs:61
333
///    5: main
334
///    6: __libc_start_main
335
///    7: _start
336
/// ```
337
///
338
/// To see a conventional struct-style Debug representation, use "{:#?}".
339
///
340
/// ```console
341
/// Error {
342
///     context: "Failed to read instrs from ./path/to/instrs.json",
343
///     source: Os {
344
///         code: 2,
345
///         kind: NotFound,
346
///         message: "No such file or directory",
347
///     },
348
/// }
349
/// ```
350
///
351
/// If none of the built-in representations are appropriate and you would prefer
352
/// to render the error and its cause chain yourself, it can be done something
353
/// like this:
354
///
355
/// ```
356
/// use anyhow::{Context, Result};
357
///
358
/// fn main() {
359
///     if let Err(err) = try_main() {
360
///         eprintln!("ERROR: {}", err);
361
///         err.chain().skip(1).for_each(|cause| eprintln!("because: {}", cause));
362
///         std::process::exit(1);
363
///     }
364
/// }
365
///
366
/// fn try_main() -> Result<()> {
367
///     # const IGNORE: &str = stringify! {
368
///     ...
369
///     # };
370
///     # Ok(())
371
/// }
372
/// ```
373
#[cfg_attr(not(doc), repr(transparent))]
374
pub struct Error {
375
    inner: Own<ErrorImpl>,
376
}
377
378
/// Iterator of a chain of source errors.
379
///
380
/// This type is the iterator returned by [`Error::chain`].
381
///
382
/// # Example
383
///
384
/// ```
385
/// use anyhow::Error;
386
/// use std::io;
387
///
388
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
389
///     for cause in error.chain() {
390
///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
391
///             return Some(io_error.kind());
392
///         }
393
///     }
394
///     None
395
/// }
396
/// ```
397
#[cfg(feature = "std")]
398
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
399
#[derive(Clone)]
400
pub struct Chain<'a> {
401
    state: crate::chain::ChainState<'a>,
402
}
403
404
/// `Result<T, Error>`
405
///
406
/// This is a reasonable return type to use throughout your application but also
407
/// for `fn main`; if you do, failures will be printed along with any
408
/// [context][Context] and a backtrace if one was captured.
409
///
410
/// `anyhow::Result` may be used with one *or* two type parameters.
411
///
412
/// ```rust
413
/// use anyhow::Result;
414
///
415
/// # const IGNORE: &str = stringify! {
416
/// fn demo1() -> Result<T> {...}
417
///            // ^ equivalent to std::result::Result<T, anyhow::Error>
418
///
419
/// fn demo2() -> Result<T, OtherError> {...}
420
///            // ^ equivalent to std::result::Result<T, OtherError>
421
/// # };
422
/// ```
423
///
424
/// # Example
425
///
426
/// ```
427
/// # pub trait Deserialize {}
428
/// #
429
/// # mod serde_json {
430
/// #     use super::Deserialize;
431
/// #     use std::io;
432
/// #
433
/// #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
434
/// #         unimplemented!()
435
/// #     }
436
/// # }
437
/// #
438
/// # #[derive(Debug)]
439
/// # struct ClusterMap;
440
/// #
441
/// # impl Deserialize for ClusterMap {}
442
/// #
443
/// use anyhow::Result;
444
///
445
/// fn main() -> Result<()> {
446
///     # return Ok(());
447
///     let config = std::fs::read_to_string("cluster.json")?;
448
///     let map: ClusterMap = serde_json::from_str(&config)?;
449
///     println!("cluster info: {:#?}", map);
450
///     Ok(())
451
/// }
452
/// ```
453
pub type Result<T, E = Error> = core::result::Result<T, E>;
454
455
/// Provides the `context` method for `Result`.
456
///
457
/// This trait is sealed and cannot be implemented for types outside of
458
/// `anyhow`.
459
///
460
/// <br>
461
///
462
/// # Example
463
///
464
/// ```
465
/// use anyhow::{Context, Result};
466
/// use std::fs;
467
/// use std::path::PathBuf;
468
///
469
/// pub struct ImportantThing {
470
///     path: PathBuf,
471
/// }
472
///
473
/// impl ImportantThing {
474
///     # const IGNORE: &'static str = stringify! {
475
///     pub fn detach(&mut self) -> Result<()> {...}
476
///     # };
477
///     # fn detach(&mut self) -> Result<()> {
478
///     #     unimplemented!()
479
///     # }
480
/// }
481
///
482
/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
483
///     it.detach().context("Failed to detach the important thing")?;
484
///
485
///     let path = &it.path;
486
///     let content = fs::read(path)
487
///         .with_context(|| format!("Failed to read instrs from {}", path.display()))?;
488
///
489
///     Ok(content)
490
/// }
491
/// ```
492
///
493
/// When printed, the outermost context would be printed first and the lower
494
/// level underlying causes would be enumerated below.
495
///
496
/// ```console
497
/// Error: Failed to read instrs from ./path/to/instrs.json
498
///
499
/// Caused by:
500
///     No such file or directory (os error 2)
501
/// ```
502
///
503
/// Refer to the [Display representations] documentation for other forms in
504
/// which this context chain can be rendered.
505
///
506
/// [Display representations]: Error#display-representations
507
///
508
/// <br>
509
///
510
/// # Effect on downcasting
511
///
512
/// After attaching context of type `C` onto an error of type `E`, the resulting
513
/// `anyhow::Error` may be downcast to `C` **or** to `E`.
514
///
515
/// That is, in codebases that rely on downcasting, Anyhow's context supports
516
/// both of the following use cases:
517
///
518
///   - **Attaching context whose type is insignificant onto errors whose type
519
///     is used in downcasts.**
520
///
521
///     In other error libraries whose context is not designed this way, it can
522
///     be risky to introduce context to existing code because new context might
523
///     break existing working downcasts. In Anyhow, any downcast that worked
524
///     before adding context will continue to work after you add a context, so
525
///     you should freely add human-readable context to errors wherever it would
526
///     be helpful.
527
///
528
///     ```
529
///     # use anyhow::bail;
530
///     # use thiserror::Error;
531
///     #
532
///     # #[derive(Error, Debug)]
533
///     # #[error("???")]
534
///     # struct SuspiciousError;
535
///     #
536
///     # fn helper() -> Result<()> {
537
///     #     bail!(SuspiciousError);
538
///     # }
539
///     #
540
///     use anyhow::{Context, Result};
541
///
542
///     fn do_it() -> Result<()> {
543
///         helper().context("Failed to complete the work")?;
544
///         # const IGNORE: &str = stringify! {
545
///         ...
546
///         # };
547
///         # unreachable!()
548
///     }
549
///
550
///     fn main() {
551
///         let err = do_it().unwrap_err();
552
///         if let Some(e) = err.downcast_ref::<SuspiciousError>() {
553
///             // If helper() returned SuspiciousError, this downcast will
554
///             // correctly succeed even with the context in between.
555
///             # return;
556
///         }
557
///         # panic!("expected downcast to succeed");
558
///     }
559
///     ```
560
///
561
///   - **Attaching context whose type is used in downcasts onto errors whose
562
///     type is insignificant.**
563
///
564
///     Some codebases prefer to use machine-readable context to categorize
565
///     lower level errors in a way that will be actionable to higher levels of
566
///     the application.
567
///
568
///     ```
569
///     # use anyhow::bail;
570
///     # use thiserror::Error;
571
///     #
572
///     # #[derive(Error, Debug)]
573
///     # #[error("???")]
574
///     # struct HelperFailed;
575
///     #
576
///     # fn helper() -> Result<()> {
577
///     #     bail!("no such file or directory");
578
///     # }
579
///     #
580
///     use anyhow::{Context, Result};
581
///
582
///     fn do_it() -> Result<()> {
583
///         helper().context(HelperFailed)?;
584
///         # const IGNORE: &str = stringify! {
585
///         ...
586
///         # };
587
///         # unreachable!()
588
///     }
589
///
590
///     fn main() {
591
///         let err = do_it().unwrap_err();
592
///         if let Some(e) = err.downcast_ref::<HelperFailed>() {
593
///             // If helper failed, this downcast will succeed because
594
///             // HelperFailed is the context that has been attached to
595
///             // that error.
596
///             # return;
597
///         }
598
///         # panic!("expected downcast to succeed");
599
///     }
600
///     ```
601
pub trait Context<T, E>: context::private::Sealed {
602
    /// Wrap the error value with additional context.
603
    fn context<C>(self, context: C) -> Result<T, Error>
604
    where
605
        C: Display + Send + Sync + 'static;
606
607
    /// Wrap the error value with additional context that is evaluated lazily
608
    /// only once an error does occur.
609
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
610
    where
611
        C: Display + Send + Sync + 'static,
612
        F: FnOnce() -> C;
613
}
614
615
/// Equivalent to Ok::<_, anyhow::Error>(value).
616
///
617
/// This simplifies creation of an anyhow::Result in places where type inference
618
/// cannot deduce the `E` type of the result &mdash; without needing to write
619
/// `Ok::<_, anyhow::Error>(value)`.
620
///
621
/// One might think that `anyhow::Result::Ok(value)` would work in such cases
622
/// but it does not.
623
///
624
/// ```console
625
/// error[E0282]: type annotations needed for `std::result::Result<i32, E>`
626
///   --> src/main.rs:11:13
627
///    |
628
/// 11 |     let _ = anyhow::Result::Ok(1);
629
///    |         -   ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the enum `Result`
630
///    |         |
631
///    |         consider giving this pattern the explicit type `std::result::Result<i32, E>`, where the type parameter `E` is specified
632
/// ```
633
#[allow(non_snake_case)]
634
0
pub fn Ok<T>(t: T) -> Result<T> {
635
0
    Result::Ok(t)
636
0
}
637
638
// Not public API. Referenced by macro-generated code.
639
#[doc(hidden)]
640
pub mod __private {
641
    use crate::Error;
642
    use alloc::fmt;
643
    use core::fmt::Arguments;
644
645
    #[doc(hidden)]
646
    pub use crate::ensure::{BothDebug, NotBothDebug};
647
    #[doc(hidden)]
648
    pub use alloc::format;
649
    #[doc(hidden)]
650
    pub use core::result::Result::Err;
651
    #[doc(hidden)]
652
    pub use core::{concat, format_args, stringify};
653
654
    #[doc(hidden)]
655
    pub mod kind {
656
        #[doc(hidden)]
657
        pub use crate::kind::{AdhocKind, TraitKind};
658
659
        #[cfg(feature = "std")]
660
        #[doc(hidden)]
661
        pub use crate::kind::BoxedKind;
662
    }
663
664
    #[doc(hidden)]
665
    #[inline]
666
    #[cold]
667
0
    pub fn format_err(args: Arguments) -> Error {
668
        #[cfg(anyhow_no_fmt_arguments_as_str)]
669
        let fmt_arguments_as_str = None::<&str>;
670
        #[cfg(not(anyhow_no_fmt_arguments_as_str))]
671
0
        let fmt_arguments_as_str = args.as_str();
672
673
0
        if let Some(message) = fmt_arguments_as_str {
674
            // anyhow!("literal"), can downcast to &'static str
675
0
            Error::msg(message)
676
        } else {
677
            // anyhow!("interpolate {var}"), can downcast to String
678
0
            Error::msg(fmt::format(args))
679
        }
680
0
    }
681
682
    #[doc(hidden)]
683
    #[inline]
684
    #[cold]
685
    #[must_use]
686
0
    pub fn must_use(error: Error) -> Error {
687
0
        error
688
0
    }
689
}