From 589289b87792d2d303fb60dd9180b6d1921b4a80 Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 13:16:03 -0400 Subject: [PATCH 1/8] Add `--stack-trace` flag using `backtrace` feature Signed-off-by: Matt Wilkinson --- src/main.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 45440a76..729b7789 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,6 +59,14 @@ struct Cli { )] pub(crate) output: OutputKind, + #[clap( + short = 't', + long = "stack-trace", + help = "Print stack trace on error", + global = true + )] + pub(crate) stack_trace: bool, + #[clap(subcommand)] command: CliCommand, } @@ -150,7 +158,7 @@ async fn main() { 0 } Err(e) => { - let trace = e + let error_chain = e .chain() .skip(1) .map(|e| format!("{}", e)) @@ -161,17 +169,24 @@ async fn main() { let mut map = HashMap::new(); map.insert("success".to_string(), json!(false)); map.insert("error".to_string(), json!(e.to_string())); - if !trace.is_empty() { - map.insert("trace".to_string(), json!(trace)); + if !error_chain.is_empty() { + map.insert("chain".to_string(), json!(error_chain)); + } + + if cli.stack_trace { + map.insert("stacktrace".to_string(), json!(e.backtrace().to_string())); } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap()); } OutputKind::Text => { eprintln!("\n{}", e); - if !trace.is_empty() { - eprintln!("Error trace:"); - eprintln!("{}", trace.join("\n")); + if !error_chain.is_empty() { + eprintln!("Error chain:"); + eprintln!("{}", error_chain.join("\n")); + } + if cli.stack_trace { + eprintln!("\n{:?}", e.backtrace()); } } } From 42b216cb33e4035d016b25078a79e8df3d08876a Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 15:05:46 -0400 Subject: [PATCH 2/8] if let Some(bt) Signed-off-by: Matt Wilkinson --- src/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 729b7789..155308e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -174,7 +174,9 @@ async fn main() { } if cli.stack_trace { - map.insert("stacktrace".to_string(), json!(e.backtrace().to_string())); + if let Some(bt) = e.backtrace() { + map.insert("stacktrace".to_string(), json!(e.backtrace().to_string())); + } } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap()); @@ -186,7 +188,10 @@ async fn main() { eprintln!("{}", error_chain.join("\n")); } if cli.stack_trace { - eprintln!("\n{:?}", e.backtrace()); + if let Some(bt) = e.backtrace() { + eprintln!("Stack trace:"); + eprintln!("\n{:?}", bt); + } } } } From 2adfdc695387cb8df3978848164dccb94b2c57eb Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 18:06:32 -0400 Subject: [PATCH 3/8] bt fix Signed-off-by: Matt Wilkinson --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 155308e8..6914d10e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -175,7 +175,7 @@ async fn main() { if cli.stack_trace { if let Some(bt) = e.backtrace() { - map.insert("stacktrace".to_string(), json!(e.backtrace().to_string())); + map.insert("stacktrace".to_string(), json!(bt.to_string())); } } From ee8e2e3ec8406d9b0e7fa57c6326d461f80d4b76 Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 18:15:47 -0400 Subject: [PATCH 4/8] match Signed-off-by: Matt Wilkinson --- src/main.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6914d10e..ffc85ad3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -174,8 +174,16 @@ async fn main() { } if cli.stack_trace { - if let Some(bt) = e.backtrace() { - map.insert("stacktrace".to_string(), json!(bt.to_string())); + match e.backtrace() { + Some(bt) => { + map.insert("stack_trace".to_string(), json!(bt.to_string())); + } + None => { + map.insert( + "stack_trace".to_string(), + json!("No stack trace available".to_string()), + ); + } } } @@ -188,9 +196,13 @@ async fn main() { eprintln!("{}", error_chain.join("\n")); } if cli.stack_trace { - if let Some(bt) = e.backtrace() { - eprintln!("Stack trace:"); - eprintln!("\n{:?}", bt); + match e.backtrace() { + Some(bt) => { + eprintln!("\nStack trace:\n{}", bt); + } + None => { + eprintln!("\nNo stack trace available"); + } } } } From 9a7d6387374d81895d8212ba8a2129cfff7ac66f Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 22:56:32 -0400 Subject: [PATCH 5/8] use anyhow `backtrace` feature Signed-off-by: Matt Wilkinson --- Cargo.lock | 3 +++ Cargo.toml | 2 +- src/main.rs | 38 +++++++++----------------------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f271d058..5217b34a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,9 @@ name = "anyhow" version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" +dependencies = [ + "backtrace", +] [[package]] name = "ascii_tree" diff --git a/Cargo.toml b/Cargo.toml index 7ba04cb2..7f25cc9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.60.0" maintenance = {status = "actively-developed"} [dependencies] -anyhow = "1.0.51" +anyhow = {version = "1.0.51", features = ["backtrace"]} async-nats = "0.18.0" atelier_core = "0.2" bytes = "1.0" diff --git a/src/main.rs b/src/main.rs index ffc85ad3..0514a1c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,14 +59,6 @@ struct Cli { )] pub(crate) output: OutputKind, - #[clap( - short = 't', - long = "stack-trace", - help = "Print stack trace on error", - global = true - )] - pub(crate) stack_trace: bool, - #[clap(subcommand)] command: CliCommand, } @@ -173,18 +165,10 @@ async fn main() { map.insert("chain".to_string(), json!(error_chain)); } - if cli.stack_trace { - match e.backtrace() { - Some(bt) => { - map.insert("stack_trace".to_string(), json!(bt.to_string())); - } - None => { - map.insert( - "stack_trace".to_string(), - json!("No stack trace available".to_string()), - ); - } - } + let backtrace = e.backtrace().to_string(); + + if !backtrace.is_empty() { + map.insert("stack_trace".to_string(), json!(backtrace)); } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap()); @@ -195,15 +179,11 @@ async fn main() { eprintln!("Error chain:"); eprintln!("{}", error_chain.join("\n")); } - if cli.stack_trace { - match e.backtrace() { - Some(bt) => { - eprintln!("\nStack trace:\n{}", bt); - } - None => { - eprintln!("\nNo stack trace available"); - } - } + + let backtrace = e.backtrace().to_string(); + + if !backtrace.is_empty() { + eprintln!("\nStack trace:\n{}", backtrace); } } } From d6ef6afc5e7ef3cf028a602cdf05188a91fb99ee Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 23:06:35 -0400 Subject: [PATCH 6/8] Use an `Option` for possible backtrace values Signed-off-by: Matt Wilkinson --- src/main.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0514a1c5..c6c203ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -156,34 +156,38 @@ async fn main() { .map(|e| format!("{}", e)) .collect::>(); + let backtrace = match e.backtrace().to_string() { + s if s.is_empty() => None, + s if s == "disabled backtrace" => None, + s => Some(s), + }; + match output_kind { OutputKind::Json => { let mut map = HashMap::new(); map.insert("success".to_string(), json!(false)); map.insert("error".to_string(), json!(e.to_string())); + if !error_chain.is_empty() { map.insert("chain".to_string(), json!(error_chain)); } - let backtrace = e.backtrace().to_string(); - - if !backtrace.is_empty() { - map.insert("stack_trace".to_string(), json!(backtrace)); + if let Some(bt) = backtrace { + map.insert("stack_trace".to_string(), json!(bt)); } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap()); } OutputKind::Text => { eprintln!("\n{}", e); + if !error_chain.is_empty() { eprintln!("Error chain:"); eprintln!("{}", error_chain.join("\n")); } - let backtrace = e.backtrace().to_string(); - - if !backtrace.is_empty() { - eprintln!("\nStack trace:\n{}", backtrace); + if let Some(bt) = backtrace { + eprintln!("\nStack trace:\n{}", bt); } } } From 0c17049720aeab3adea08c3c04bc0cf1ee2e46c8 Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 23:13:06 -0400 Subject: [PATCH 7/8] simplify text output by using `anyhow`'s debug format Signed-off-by: Matt Wilkinson --- src/main.rs | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index c6c203ee..726bc5fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,45 +150,36 @@ async fn main() { 0 } Err(e) => { - let error_chain = e - .chain() - .skip(1) - .map(|e| format!("{}", e)) - .collect::>(); - - let backtrace = match e.backtrace().to_string() { - s if s.is_empty() => None, - s if s == "disabled backtrace" => None, - s => Some(s), - }; - match output_kind { OutputKind::Json => { let mut map = HashMap::new(); map.insert("success".to_string(), json!(false)); map.insert("error".to_string(), json!(e.to_string())); + let error_chain = e + .chain() + .skip(1) + .map(|e| format!("{}", e)) + .collect::>(); + if !error_chain.is_empty() { - map.insert("chain".to_string(), json!(error_chain)); + map.insert("error_chain".to_string(), json!(error_chain)); } + let backtrace = match e.backtrace().to_string() { + s if s.is_empty() => None, + s if s == "disabled backtrace" => None, + s => Some(s), + }; + if let Some(bt) = backtrace { - map.insert("stack_trace".to_string(), json!(bt)); + map.insert("backtrace".to_string(), json!(bt)); } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap()); } OutputKind::Text => { - eprintln!("\n{}", e); - - if !error_chain.is_empty() { - eprintln!("Error chain:"); - eprintln!("{}", error_chain.join("\n")); - } - - if let Some(bt) = backtrace { - eprintln!("\nStack trace:\n{}", bt); - } + eprintln!("\n{:?}", e); } } 1 From 4d032242168850dae558e50efc4e5acc0f08b283 Mon Sep 17 00:00:00 2001 From: Matt Wilkinson Date: Mon, 5 Sep 2022 23:16:24 -0400 Subject: [PATCH 8/8] simplify backtrace json code Signed-off-by: Matt Wilkinson --- src/main.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 726bc5fd..283f21ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -166,14 +166,10 @@ async fn main() { map.insert("error_chain".to_string(), json!(error_chain)); } - let backtrace = match e.backtrace().to_string() { - s if s.is_empty() => None, - s if s == "disabled backtrace" => None, - s => Some(s), - }; - - if let Some(bt) = backtrace { - map.insert("backtrace".to_string(), json!(bt)); + let backtrace = e.backtrace().to_string(); + + if !backtrace.is_empty() && backtrace != "disabled backtrace" { + map.insert("backtrace".to_string(), json!(backtrace)); } eprintln!("\n{}", serde_json::to_string_pretty(&map).unwrap());