Closed cyphar closed 4 years ago
The functionality is configurable, just not via Option
. You need to implement GenerateBacktrace
for your type and then you can rely on whatever logic you want. An untested sketch:
use snafu::{Backtrace, GenerateBacktrace};
use std::sync::atomic::{AtomicBool, Ordering};
struct GlobalBacktrace(Option<Backtrace>);
static ENABLED: AtomicBool = AtomicBool::new(false);
impl GenerateBacktrace for GlobalBacktrace {
fn generate() -> Self {
Self(if ENABLED.load(Ordering::SeqCst) {
Some(GenerateBacktrace::generate())
} else {
None
})
}
fn as_backtrace(&self) -> Option<&Backtrace> {
self.0.as_ref()
}
}
I will admit, I didn't think to implement GenerateBacktrace
on a custom struct -- that should solve my problem. Thanks, and sorry for the noise.
Right now, the only way to have runtime-controlled optional backtraces for some library or application is to use
Option<snafu::Backtrace>
and then the user must setRUST_BACKTRACE
orRUST_LIB_BACKTRACE
in order to enable it. While this does mean that the same UX for "getting a backtrace" is present for allsnafu
-based Rust programs, it has the major downside of making the UX feel strange for programs which are not necessarily related to Rust. For instance, a user may find it odd for a shared library (written in Rust) used by a C program to require you to setRUST_LIB_BACKTRACE=1
in the environment.In addition, the fact it's set once and cannot be changed means that for long-running processes it's necessary to restart them in order to enable debugging -- when ideally you should be able to enable debugging after the program has been started and handled more than one error.