Provide error reporter and use it in the arti binary

This commit is contained in:
Ian Jackson 2022-02-18 11:34:53 +00:00
parent ccb4604237
commit 8c4726b55e
5 changed files with 50 additions and 1 deletions

1
Cargo.lock generated
View File

@ -86,6 +86,7 @@ dependencies = [
"rlimit",
"serde",
"tokio",
"tor-error",
"tor-rtcompat",
"tor-socksproto",
"tracing",

View File

@ -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"}

View File

@ -125,7 +125,11 @@ async fn run<R: Runtime>(
)
}
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.

View File

@ -41,6 +41,9 @@ use derive_more::Display;
mod internal;
pub use internal::*;
mod report;
pub use report::*;
mod truncated;
pub use truncated::*;

View File

@ -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<E>(pub E);
impl<E> Display for Report<E> where E: AsRef<dyn std::error::Error> {
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, R>(e: E) -> R where E: AsRef<dyn std::error::Error> {
eprintln!("{}", Report(e));
std::process::exit(127)
}