Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RUST_LIB_BACKTRACE variable #38

Merged
merged 5 commits into from May 6, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 45 additions & 10 deletions src/lib.rs
Expand Up @@ -36,6 +36,7 @@
//! [medium](Verbosity::Medium) and `RUST_BACKTRACE=full` to
//! [full](Verbosity::Full) verbosity levels.

use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, ErrorKind};
use std::panic::PanicInfo;
Expand Down Expand Up @@ -73,13 +74,26 @@ pub enum Verbosity {
impl Verbosity {
/// Get the verbosity level from the `RUST_BACKTRACE` env variable.
pub fn from_env() -> Self {
match std::env::var("RUST_BACKTRACE") {
Ok(ref x) if x == "full" => Verbosity::Full,
Ok(_) => Verbosity::Medium,
Err(_) => Verbosity::Minimal,
Self::convert_env(env::var("RUST_BACKTRACE").ok())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these methods follow std's example and make some effort to cache these values?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, I think this is fine as-is. I'd argue that panic printers and thus verbosity instances are generally constructed only few times per app-run and it wouldn't be worth the effort.

}

pub fn lib_from_env() -> Self {
Self::convert_env(
env::var("RUST_LIB_BACKTRACE")
.or_else(|_| env::var("RUST_BACKTRACE"))
.ok(),
)
}

fn convert_env(env: Option<String>) -> Self {
match env {
Some(ref x) if x == "full" => Verbosity::Full,
Some(_) => Verbosity::Medium,
None => Verbosity::Minimal,
}
}
}

// ============================================================================================== //
// [Panic handler and install logic] //
// ============================================================================================== //
Expand Down Expand Up @@ -416,7 +430,9 @@ pub type Settings = BacktracePrinter;
pub struct BacktracePrinter {
message: String,
verbosity: Verbosity,
lib_verbosity: Verbosity,
strip_function_hash: bool,
is_panic_handler: bool,
colors: ColorScheme,
filters: Vec<Box<FilterCallback>>,
}
Expand All @@ -425,9 +441,11 @@ impl Default for BacktracePrinter {
fn default() -> Self {
Self {
verbosity: Verbosity::from_env(),
lib_verbosity: Verbosity::lib_from_env(),
message: "The application panicked (crashed).".to_owned(),
strip_function_hash: false,
colors: ColorScheme::classic(),
is_panic_handler: false,
filters: vec![Box::new(default_frame_filter)],
}
}
Expand Down Expand Up @@ -458,12 +476,20 @@ impl BacktracePrinter {

/// Controls the verbosity level.
///
/// Defaults to `Verbosity::get_env()`.
/// Defaults to `Verbosity::from_env()`.
pub fn verbosity(mut self, v: Verbosity) -> Self {
self.verbosity = v;
self
}

/// Controls the lib verbosity level.
///
/// Defaults to `Verbosity::lib_from_env()`.
pub fn lib_verbosity(mut self, v: Verbosity) -> Self {
self.lib_verbosity = v;
self
}

/// Controls whether the hash part of functions is stripped.
///
/// Defaults to `false`.
Expand Down Expand Up @@ -514,9 +540,10 @@ impl BacktracePrinter {
///
/// This can be used if you want to combine the handler with other handlers.
pub fn into_panic_handler(
self,
mut self,
out: impl WriteColor + Sync + Send + 'static,
) -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
self.is_panic_handler = true;
let out_stream_mutex = Mutex::new(out);
Box::new(move |pi| {
let mut lock = out_stream_mutex.lock().unwrap();
Expand Down Expand Up @@ -653,15 +680,15 @@ impl BacktracePrinter {
}

// Print some info on how to increase verbosity.
if self.verbosity == Verbosity::Minimal {
if self.current_verbosity() == Verbosity::Minimal {
write!(out, "\nBacktrace omitted. Run with ")?;
out.set_color(&self.colors.env_var)?;
write!(out, "RUST_BACKTRACE=1")?;
out.reset()?;
writeln!(out, " environment variable to display it.")?;
}
if self.verbosity <= Verbosity::Medium {
if self.verbosity == Verbosity::Medium {
if self.current_verbosity() <= Verbosity::Medium {
if self.current_verbosity() == Verbosity::Medium {
// If exactly medium, no newline was printed before.
writeln!(out)?;
}
Expand All @@ -673,12 +700,20 @@ impl BacktracePrinter {
writeln!(out, " to include source snippets.")?;
}

if self.verbosity >= Verbosity::Medium {
if self.current_verbosity() >= Verbosity::Medium {
self.print_trace(&backtrace::Backtrace::new(), out)?;
}

Ok(())
}

fn current_verbosity(&self) -> Verbosity {
if self.is_panic_handler {
self.verbosity
} else {
self.lib_verbosity
}
}
}

// ============================================================================================== //
Expand Down