Provide error reporter and use it in the arti binary
This commit is contained in:
parent
ccb4604237
commit
8c4726b55e
|
@ -86,6 +86,7 @@ dependencies = [
|
||||||
"rlimit",
|
"rlimit",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tor-error",
|
||||||
"tor-rtcompat",
|
"tor-rtcompat",
|
||||||
"tor-socksproto",
|
"tor-socksproto",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
@ -21,6 +21,7 @@ journald = [ "tracing-journald" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arti-client = { package="arti-client", path = "../arti-client", version = "0.0.4", default-features=false}
|
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-rtcompat = { path="../tor-rtcompat", version = "0.0.4", default-features=false }
|
||||||
tor-socksproto = { path="../tor-socksproto", version = "0.0.3"}
|
tor-socksproto = { path="../tor-socksproto", version = "0.0.3"}
|
||||||
arti-config = { path="../arti-config", version = "0.0.4"}
|
arti-config = { path="../arti-config", version = "0.0.4"}
|
||||||
|
|
|
@ -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
|
// We describe a default here, rather than using `default()`, because the
|
||||||
// correct behavior is different depending on whether the filename is given
|
// correct behavior is different depending on whether the filename is given
|
||||||
// explicitly or not.
|
// explicitly or not.
|
||||||
|
|
|
@ -41,6 +41,9 @@ use derive_more::Display;
|
||||||
mod internal;
|
mod internal;
|
||||||
pub use internal::*;
|
pub use internal::*;
|
||||||
|
|
||||||
|
mod report;
|
||||||
|
pub use report::*;
|
||||||
|
|
||||||
mod truncated;
|
mod truncated;
|
||||||
pub use truncated::*;
|
pub use truncated::*;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in New Issue