shepmaster / snafu

Easily assign underlying errors into domain-specific errors while adding context
https://docs.rs/snafu/
Apache License 2.0
1.4k stars 60 forks source link

Is there a way to disable backtraces at runtime? #368

Open ankrgyl opened 1 year ago

ankrgyl commented 1 year ago

From what I can tell, backtraces are enabled/disabled depending on the feature flags a crate is compiled with. Is there a way to set a runtime flag for whether or not to disable them?

8573 commented 1 year ago

IIRC, the environment variable RUST_BACKTRACE, set to 0 or 1, controls them if the backtrace field in an error struct or enum variant has type Option<Backtrace>.

ankrgyl commented 1 year ago

That's what I thought too... I did a bit of further digging and realized it has to do with how I'm using Whatever. Specifically, in the following repro, no matter how the environment variables are set, bar() always captures a stack trace. This might just be known behavior, so apologies if it's redundant!

main.rs

use snafu::{whatever, Backtrace, ErrorCompat, Snafu, Whatever};

#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum CompileError {
    #[snafu(display("Parser error: {}", msg))]
    SyntaxError {
        msg: String,
        backtrace: Option<Backtrace>,
    },
}

fn foo() -> Result<(), CompileError> {
    SyntaxSnafu { msg: "foo" }.fail()
}

fn bar() -> Result<(), Whatever> {
    whatever!("bar");
}

fn main() {
    eprintln!("Calling foo");
    match foo() {
        Ok(_) => {}
        Err(err) => {
            eprintln!("Error: {:?}", err);
            if let Some(bt) = ErrorCompat::backtrace(&err) {
                eprintln!("{:?}", bt);
            }
        }
    }

    eprintln!("Calling bar");
    match bar() {
        Ok(_) => {}
        Err(err) => {
            eprintln!("Error: {:?}", err);
            if let Some(bt) = ErrorCompat::backtrace(&err) {
                eprintln!("{:?}", bt);
            }
        }
    }
}

If you run this, you'll see something like:

Calling foo
Error: SyntaxError { msg: "foo", backtrace: None }
Calling bar
Error: Whatever { source: None, message: "bar", backtrace: Backtrace(   0: backtrace::backtrace::libunwind::trace
             at /Users/ankur/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.66/src/backtrace/libunwind.rs:93:5
      backtrace::backtrace::trace_unsynchronized
             at /Users/ankur/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.66/src/backtrace/mod.rs:66:5
   1: backtrace::backtrace::trace
...