eyre-rs / color-eyre

Custom hooks for colorful human oriented error reports via panics and the eyre crate
Other
958 stars 57 forks source link

Construct a new `Handler` after already having created one / modify handler #149

Open Emilgardis opened 8 months ago

Emilgardis commented 8 months ago

I wanted to switch the style of a specific report, this to circumvent https://github.com/eyre-rs/color-eyre/issues/122 not working and it not being formatted optimally with the env section being repeated.

I have the following code

pub fn add_reports(
    origin: eyre::Report,
    iter: impl IntoIterator<Item = eyre::Report>,
) -> eyre::Report {
    use color_eyre::{Section as _, SectionExt as _};
    iter.into_iter().fold(origin, |report, mut e| {
        // Create a new Handler
        let custom_handler = color_eyre::config::HookBuilder::new()
            // disable env section
            .display_env_section(false)

            .into_hooks() // <---- Panic here!!!

            .1
            .into_eyre_hook();
        let mut custom_handler = custom_handler(e.source().unwrap_or(e.root_cause()));
        let custom_handler = custom_handler
            .downcast_mut::<color_eyre::Handler>()
            .unwrap();

        // get the current Handler
        let handler = e.handler_mut();
        let handler = handler.downcast_mut::<color_eyre::Handler>().unwrap();

        std::mem::swap(handler, custom_handler);

        report.section(format!("{e:?}").header("Error:"))
    })
}

but I get a panic:

The application panicked (crashed).
Message:  could not set the provided `Theme` via `color_spantrace::set_theme` globally as another was already set: InstallThemeError
Location: .cargo/registry/src/index.crates.io-6f17d22bba15001f/color-eyre-0.6.2/src/config.rs:756

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

The issue is that HookBuilder::into_hooks calls color_spantrace::set_theme

https://github.com/eyre-rs/color-eyre/blame/6a9b70b44d11e0540b9dbc325149bab2a5d505b6/src/config.rs#L756

This issue persists on the current master branch as well.

Now, I'm not sure if this is truly the way to go so I have two propositions that would make me happy.

  1. Provide a way to create a EyreHook without set_theme (this would also need a way to get the location I discovered, to propagate into the new handler)
  2. Enable a way to change the settings on a specific report, e.g report.handler_mut().downcast_mut::<color_eyre::Handler>().unwrap().display_env_section = false

I think that nr. 2 is the best option, since it makes it easy to customize a report "in-flight"

Emilgardis commented 8 months ago

Would the project be open to a PR that implements nr. 2? Introducing setters and getters for the fields on https://github.com/eyre-rs/color-eyre/blob/4a5297d30b0f0754a3bbc47b71bb55b04960c0ad/src/lib.rs#L397-L417, or possibly even making them pub but making Handler #[non_exhaustive]