commit d6b9b8bf0c98d32d7ccc363e1f5ad620df0c3d64
parent 2ee07ea1d8a7e42ca6532f461f2aeeec4db629be
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Mon, 16 Mar 2020 18:16:49 +0100
Merge pull request #876 from BlackDex/log-panics
Make panics logable (as warn)
Diffstat:
3 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -119,6 +119,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
name = "bitwarden_rs"
version = "1.0.0"
dependencies = [
+ "backtrace",
"chashmap",
"chrono",
"data-encoding",
diff --git a/Cargo.toml b/Cargo.toml
@@ -118,6 +118,9 @@ idna = "0.2.0"
# CLI argument parsing
structopt = "0.3.11"
+# Logging panics to logfile instead stderr only
+backtrace = "0.3.45"
+
[patch.crates-io]
# Use newest ring
rocket = { git = 'https://github.com/SergioBenitez/Rocket', rev = 'b95b6765e1cc8be7c1e7eaef8a9d9ad940b0ac13' }
diff --git a/src/main.rs b/src/main.rs
@@ -20,11 +20,14 @@ extern crate derive_more;
#[macro_use]
extern crate num_derive;
+extern crate backtrace;
+
use std::{
fs::create_dir_all,
path::Path,
process::{exit, Command},
str::FromStr,
+ panic, thread, fmt // For panic logging
};
#[macro_use]
@@ -42,6 +45,16 @@ pub use error::{Error, MapResult};
use structopt::StructOpt;
+// Used for catching panics and log them to file instead of stderr
+use backtrace::Backtrace;
+struct Shim(Backtrace);
+
+impl fmt::Debug for Shim {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(fmt, "\n{:?}", self.0)
+ }
+}
+
#[derive(Debug, StructOpt)]
#[structopt(name = "bitwarden_rs", about = "A Bitwarden API server written in Rust")]
struct Opt {
@@ -142,6 +155,44 @@ fn init_logging(level: log::LevelFilter) -> Result<(), fern::InitError> {
logger.apply()?;
+ // Catch panics and log them instead of default output to StdErr
+ panic::set_hook(Box::new(|info| {
+ let backtrace = Backtrace::new();
+
+ let thread = thread::current();
+ let thread = thread.name().unwrap_or("unnamed");
+
+ let msg = match info.payload().downcast_ref::<&'static str>() {
+ Some(s) => *s,
+ None => match info.payload().downcast_ref::<String>() {
+ Some(s) => &**s,
+ None => "Box<Any>",
+ },
+ };
+
+ match info.location() {
+ Some(location) => {
+ error!(
+ target: "panic", "thread '{}' panicked at '{}': {}:{}{:?}",
+ thread,
+ msg,
+ location.file(),
+ location.line(),
+ Shim(backtrace)
+ );
+ }
+ None => {
+ error!(
+ target: "panic",
+ "thread '{}' panicked at '{}'{:?}",
+ thread,
+ msg,
+ Shim(backtrace)
+ )
+ }
+ }
+ }));
+
Ok(())
}