From 8c4726b55e829d6e9bd1000f96a7f78c46c18546 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 18 Feb 2022 11:34:53 +0000 Subject: [PATCH] Provide error reporter and use it in the arti binary --- Cargo.lock | 1 + crates/arti/Cargo.toml | 1 + crates/arti/src/main.rs | 6 ++++- crates/tor-error/src/lib.rs | 3 +++ crates/tor-error/src/report.rs | 40 ++++++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 crates/tor-error/src/report.rs diff --git a/Cargo.lock b/Cargo.lock index d8aba3640..ef38e6d3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,6 +86,7 @@ dependencies = [ "rlimit", "serde", "tokio", + "tor-error", "tor-rtcompat", "tor-socksproto", "tracing", diff --git a/crates/arti/Cargo.toml b/crates/arti/Cargo.toml index f8d30d00a..7f1e39273 100644 --- a/crates/arti/Cargo.toml +++ b/crates/arti/Cargo.toml @@ -21,6 +21,7 @@ journald = [ "tracing-journald" ] [dependencies] arti-client = { package="arti-client", path = "../arti-client", version = "0.0.4", default-features=false} +tor-error = { path="../tor-error", version = "0.0.1", default-features=false } tor-rtcompat = { path="../tor-rtcompat", version = "0.0.4", default-features=false } tor-socksproto = { path="../tor-socksproto", version = "0.0.3"} arti-config = { path="../arti-config", version = "0.0.4"} diff --git a/crates/arti/src/main.rs b/crates/arti/src/main.rs index 0bce0c4a4..d5fb444ad 100644 --- a/crates/arti/src/main.rs +++ b/crates/arti/src/main.rs @@ -125,7 +125,11 @@ async fn run( ) } -fn main() -> Result<()> { +fn main() { + main_main().unwrap_or_else(tor_error::report_and_exit) +} + +fn main_main() -> Result<()> { // We describe a default here, rather than using `default()`, because the // correct behavior is different depending on whether the filename is given // explicitly or not. diff --git a/crates/tor-error/src/lib.rs b/crates/tor-error/src/lib.rs index d3e50a3a2..25c4daf91 100644 --- a/crates/tor-error/src/lib.rs +++ b/crates/tor-error/src/lib.rs @@ -41,6 +41,9 @@ use derive_more::Display; mod internal; pub use internal::*; +mod report; +pub use report::*; + mod truncated; pub use truncated::*; diff --git a/crates/tor-error/src/report.rs b/crates/tor-error/src/report.rs new file mode 100644 index 000000000..8ebcde671 --- /dev/null +++ b/crates/tor-error/src/report.rs @@ -0,0 +1,40 @@ +//! The Report type which reports errors nicely + +use std::fmt::{self, Debug, Display}; + +/// Wraps any Error, providing a nicely-reporting Display impl +#[derive(Debug, Copy, Clone)] +pub struct Report(pub E); + +impl Display for Report where E: AsRef { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn inner(mut e: &dyn std::error::Error, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(progname) = std::env::args().next() { + write!(f, "{}: ", progname)?; + } + write!(f, "error")?; + let mut last = String::new(); + loop { + let this = e.to_string(); + if ! last.contains(&this) { + write!(f, ": {}", &this)?; + } + last = this; + + if let Some(ne) = e.source() { + e = ne + } else { + break + } + } + Ok(()) + } + + inner(self.0.as_ref(), f) + } +} + +pub fn report_and_exit(e: E) -> R where E: AsRef { + eprintln!("{}", Report(e)); + std::process::exit(127) +}