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

Print a backtrace/spantrace to debug logs not to stderr #130

Open gibfahn opened 1 year ago

gibfahn commented 1 year ago

Sorry if this is in the docs/examples and I missed it, but I'm struggling to work out how I would manually generate a backtrace or a spantrace from a color_eyre::Result.

The use-case is a user-facing CLI, where I write trace logs to a file. When something goes wrong printing a backtrace tends to confuse users, and makes them even more likely to miss the Suggestion: I added that tells them exactly what to do 😁

However the backtrace is useful for me, when I didn't add enough context to each layer of the error stack to see where the error propagated.

The CLI tells people to ask for support and attach the log file in the issue, and so I'd like to tracing::debug!() log the spantrace so it persists in the log file.

gibfahn commented 1 year ago

I tried a few more things, and as far as I can tell:

A spantrace is mostly useful if you have #[instrument] calls in all your functions. Setting this up means the compact tracing logs start including the function name in them (with as far as I can tell no way to disable it). So avoiding this for now.

A backtrace is more likely to be what I want, but the RUST_BACKTRACE style env vars are only checked at color_eyre setup (config), so changing them later doesn't do anything.

I think what I want is something like this:

    if std::env::var("RUST_BACKTRACE").is_err() {
        std::env::set_var("RUST_BACKTRACE", "1");
    }

    // Rest of program execution goes here.

    // Print the backtrace.
    debug!("Run result: {result}");
    if let Err(report) = result.as_mut() {
        if let Some(handler) = report.handler_mut().downcast_mut::<color_eyre::Handler>() {
            if let Some(backtrace) = handler.backtrace_mut() {
                // Remove the backtrace.
                let _ = backtrace.take();
            }
        }
    }

    // Return the program result, not printing the backtrace.
    return result;

but handler.backtrace_mut() isn't a thing.