//! An error report handler for panics and the [`eyre`] crate for colorful, consistent, and well //! formatted error reports for all kinds of errors. //! //! ## TLDR //! //! `color_eyre` helps you build error reports that look like this: //! //!
color-eyre on hooked [$!] is 📦 v0.5.0 via 🦀 v1.44.0 //! ❯ cargo run --example custom_section //! Finished dev [unoptimized + debuginfo] target(s) in 0.04s //! Running `target/debug/examples/custom_section` //! Error: //! 0: Unable to read config //! 1: cmd exited with non-zero status code //! //! Stderr: //! cat: fake_file: No such file or directory //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! //! 0: custom_section::output2 with self="cat" "fake_file" //! at examples/custom_section.rs:14 //! 1: custom_section::read_file with path="fake_file" //! at examples/custom_section.rs:58 //! 2: custom_section::read_config //! at examples/custom_section.rs:63 //! //! Suggestion: try using a file that exists next time//! //! ## Setup //! //! Add the following to your toml file: //! //! ```toml //! [dependencies] //! color-eyre = "0.5" //! ``` //! //! And install the panic and error report handlers: //! //! ```rust //! use color_eyre::eyre::Result; //! //! fn main() -> Result<()> { //! color_eyre::install()?; //! //! // ... //! # Ok(()) //! } //! ``` //! //! ### Disabling tracing support //! //! If you don't plan on using `tracing_error` and `SpanTrace` you can disable the //! tracing integration to cut down on unused dependencies: //! //! ```toml //! [dependencies] //! color-eyre = { version = "0.5", default-features = false } //! ``` //! //! ### Disabling SpanTrace capture by default //! //! color-eyre defaults to capturing span traces. This is because `SpanTrace` //! capture is significantly cheaper than `Backtrace` capture. However, like //! backtraces, span traces are most useful for debugging applications, and it's //! not uncommon to want to disable span trace capture by default to keep noise out //! developer. //! //! To disable span trace capture you must explicitly set one of the env variables //! that regulate `SpanTrace` capture to `"0"`: //! //! ```rust //! if std::env::var("RUST_SPANTRACE").is_err() { //! std::env::set_var("RUST_SPANTRACE", "0"); //! } //! ``` //! //! ### Improving perf on debug builds //! //! In debug mode `color-eyre` behaves noticably worse than `eyre`. This is caused //! by the fact that `eyre` uses `std::backtrace::Backtrace` instead of //! `backtrace::Backtrace`. The std version of backtrace is precompiled with //! optimizations, this means that whether or not you're in debug mode doesn't //! matter much for how expensive backtrace capture is, it will always be in the //! 10s of milliseconds to capture. A debug version of `backtrace::Backtrace` //! however isn't so lucky, and can take an order of magnitude more time to capture //! a backtrace compared to its std counterpart. //! //! Cargo [profile //! overrides](https://doc.rust-lang.org/cargo/reference/profiles.html#overrides) //! can be used to mitigate this problem. By configuring your project to always //! build `backtrace` with optimizations you should get the same performance from //! `color-eyre` that you're used to with `eyre`. To do so add the following to //! your Cargo.toml: //! //! ```toml //! [profile.dev.package.backtrace] //! opt-level = 3 //! ``` //! //! ## Features //! //! ### Multiple report format verbosity levels //! //! `color-eyre` provides 3 different report formats for how it formats the captured `SpanTrace` //! and `Backtrace`, minimal, short, and full. Take the below snippets of the output produced by [`examples/usage.rs`]: //! //! --- //! //! Running `cargo run --example usage` without `RUST_LIB_BACKTRACE` set will produce a minimal //! report like this: //! //!
color-eyre on hooked [$!] is 📦 v0.5.0 via 🦀 v1.44.0 took 2s //! ❯ cargo run --example usage //! Finished dev [unoptimized + debuginfo] target(s) in 0.04s //! Running `target/debug/examples/usage` //! Jul 05 19:15:58.026 INFO read_config:read_file{path="fake_file"}: Reading file //! Error: //! 0: Unable to read config //! 1: No such file or directory (os error 2) //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! //! 0: usage::read_file with path="fake_file" //! at examples/usage.rs:32 //! 1: usage::read_config //! at examples/usage.rs:38 //! //! Suggestion: try using a file that exists next time//! //!
color-eyre on hooked [$!] is 📦 v0.5.0 via 🦀 v1.44.0 //! ❯ RUST_LIB_BACKTRACE=1 cargo run --example usage //! Finished dev [unoptimized + debuginfo] target(s) in 0.04s //! Running `target/debug/examples/usage` //! Jul 05 19:16:02.853 INFO read_config:read_file{path="fake_file"}: Reading file //! Error: //! 0: Unable to read config //! 1: No such file or directory (os error 2) //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! //! 0: usage::read_file with path="fake_file" //! at examples/usage.rs:32 //! 1: usage::read_config //! at examples/usage.rs:38 //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! ⋮ 5 frames hidden ⋮ //! 6: usage::read_file::haee210cb22460af3 //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:35 //! 7: usage::read_config::ha649ef4ec333524d //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:40 //! 8: usage::main::hbe443b50eac38236 //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:11 //! ⋮ 10 frames hidden ⋮ //! //! Suggestion: try using a file that exists next time//! //!
color-eyre on hooked [$!] is 📦 v0.5.0 via 🦀 v1.44.0 //! ❯ RUST_LIB_BACKTRACE=full cargo run --example usage //! Finished dev [unoptimized + debuginfo] target(s) in 0.05s //! Running `target/debug/examples/usage` //! Jul 05 19:16:06.335 INFO read_config:read_file{path="fake_file"}: Reading file //! Error: //! 0: Unable to read config //! 1: No such file or directory (os error 2) //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! //! 0: usage::read_file with path="fake_file" //! at examples/usage.rs:32 //! 30 │ } //! 31 │ //! 32 > #[instrument] //! 33 │ fn read_file(path: &str) -> Result<(), Report> { //! 34 │ info!("Reading file"); //! 1: usage::read_config //! at examples/usage.rs:38 //! 36 │ } //! 37 │ //! 38 > #[instrument] //! 39 │ fn read_config() -> Result<(), Report> { //! 40 │ read_file("fake_file") //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! ⋮ 5 frames hidden ⋮ //! 6: usage::read_file::haee210cb22460af3 //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:35 //! 33 │ fn read_file(path: &str) -> Result<(), Report> { //! 34 │ info!("Reading file"); //! 35 > Ok(std::fs::read_to_string(path).map(drop)?) //! 36 │ } //! 37 │ //! 7: usage::read_config::ha649ef4ec333524d //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:40 //! 38 │ #[instrument] //! 39 │ fn read_config() -> Result<(), Report> { //! 40 > read_file("fake_file") //! 41 │ .wrap_err("Unable to read config") //! 42 │ .suggestion("try using a file that exists next time") //! 8: usage::main::hbe443b50eac38236 //! at /home/jlusby/git/yaahc/color-eyre/examples/usage.rs:11 //! 9 │ color_eyre::install()?; //! 10 │ //! 11 > Ok(read_config()?) //! 12 │ } //! 13 │ //! ⋮ 10 frames hidden ⋮ //! //! Suggestion: try using a file that exists next time//! //! ### Custom `Section`s for error reports via [`Section`] trait //! //! The `section` module provides helpers for adding extra sections to error //! reports. Sections are disinct from error messages and are displayed //! independently from the chain of errors. Take this example of adding sections //! to contain `stderr` and `stdout` from a failed command, taken from //! [`examples/custom_section.rs`]: //! //! ```rust //! use color_eyre::{eyre::eyre, SectionExt, Section, eyre::Report}; //! use std::process::Command; //! use tracing::instrument; //! //! trait Output { //! fn output2(&mut self) -> Result
color-eyre on hooked [$!] is 📦 v0.5.0 via 🦀 v1.44.0 took 2s //! ❯ cargo run --example custom_section //! Finished dev [unoptimized + debuginfo] target(s) in 0.04s //! Running `target/debug/examples/custom_section` //! Error: //! 0: Unable to read config //! 1: cmd exited with non-zero status code //! //! Stderr: //! cat: fake_file: No such file or directory //! //! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ //! //! 0: custom_section::output2 with self="cat" "fake_file" //! at examples/custom_section.rs:14 //! 1: custom_section::read_file with path="fake_file" //! at examples/custom_section.rs:58 //! 2: custom_section::read_config //! at examples/custom_section.rs:63 //! //! Suggestion: try using a file that exists next time//! //! Only the `Stderr:` section actually gets included. The `cat` command fails, //! so stdout ends up being empty and is skipped in the final report. This gives //! us a short and concise error report indicating exactly what was attempted and //! how it failed. //! //! ### Aggregating multiple errors into one report //! //! It's not uncommon for programs like batched task runners or parsers to want //! to return an error with multiple sources. The current version of the error //! trait does not support this use case very well, though there is [work being //! done](https://github.com/rust-lang/rfcs/pull/2895) to improve this. //! //! For now however one way to work around this is to compose errors outside the //! error trait. `color-eyre` supports such composition in its error reports via //! the `Section` trait. //! //! For an example of how to aggregate errors check out [`examples/multiple_errors.rs`]. //! //! ### Custom configuration for `color-backtrace` for setting custom filters and more //! //! The pretty printing for backtraces and span traces isn't actually provided by //! `color-eyre`, but instead comes from its dependencies [`color-backtrace`] and //! [`color-spantrace`]. `color-backtrace` in particular has many more features //! than are exported by `color-eyre`, such as customized color schemes, panic //! hooks, and custom frame filters. The custom frame filters are particularly //! useful when combined with `color-eyre`, so to enable their usage we provide //! the `install` fn for setting up a custom `BacktracePrinter` with custom //! filters installed. //! //! For an example of how to setup custom filters, check out [`examples/custom_filter.rs`]. //! //! [`eyre`]: https://docs.rs/eyre //! [`tracing-error`]: https://docs.rs/tracing-error //! [`color-backtrace`]: https://docs.rs/color-backtrace //! [`eyre::EyreHandler`]: https://docs.rs/eyre/*/eyre/trait.EyreHandler.html //! [`backtrace::Backtrace`]: https://docs.rs/backtrace/*/backtrace/struct.Backtrace.html //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-spantrace`]: https://github.com/yaahc/color-spantrace //! [`Section`]: https://docs.rs/color-eyre/*/color_eyre/trait.Section.html //! [`eyre::Report`]: https://docs.rs/eyre/*/eyre/struct.Report.html //! [`eyre::Result`]: https://docs.rs/eyre/*/eyre/type.Result.html //! [`Handler`]: https://docs.rs/color-eyre/*/color_eyre/struct.Handler.html //! [`examples/usage.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/usage.rs //! [`examples/custom_filter.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/custom_filter.rs //! [`examples/custom_section.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/custom_section.rs //! [`examples/multiple_errors.rs`]: https://github.com/yaahc/color-eyre/blob/master/examples/multiple_errors.rs #![doc(html_root_url = "https://docs.rs/color-eyre/0.6.2")] #![cfg_attr(docsrs, feature(doc_cfg))] #![warn( missing_docs, rustdoc::missing_doc_code_examples, rust_2018_idioms, unreachable_pub, bad_style, const_err, dead_code, improper_ctypes, non_shorthand_field_patterns, no_mangle_generic_items, overflowing_literals, path_statements, patterns_in_fns_without_body, private_in_public, unconditional_recursion, unused, unused_allocation, unused_comparisons, unused_parens, while_true )] #![allow(clippy::try_err)] use std::sync::Arc; use backtrace::Backtrace; pub use eyre; #[doc(hidden)] pub use eyre::Report; #[doc(hidden)] pub use eyre::Result; pub use owo_colors; use section::help::HelpInfo; #[doc(hidden)] pub use section::Section as Help; pub use section::{IndentedSection, Section, SectionExt}; #[cfg(feature = "capture-spantrace")] use tracing_error::SpanTrace; #[doc(hidden)] pub use Handler as Context; pub mod config; mod fmt; mod handler; pub(crate) mod private; pub mod section; mod writers; /// A custom handler type for [`eyre::Report`] which provides colorful error /// reports and [`tracing-error`] support. /// /// # Details /// /// This type is not intended to be used directly, prefer using it via the /// [`color_eyre::Report`] and [`color_eyre::Result`] type aliases. /// /// [`eyre::Report`]: https://docs.rs/eyre/*/eyre/struct.Report.html /// [`tracing-error`]: https://docs.rs/tracing-error /// [`color_eyre::Report`]: type.Report.html /// [`color_eyre::Result`]: type.Result.html pub struct Handler { filters: Arc<[Box