Skip to main content

anyhow/
lib.rs

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