1use std::error::Error;
2use std::fmt;
3
4use tracing::Level;
5
6pub fn backtrace_enabled() -> bool {
15 matches!(
16 std::env::var("RUST_BACKTRACE").as_ref().map(String::as_str),
17 Ok("1") | Ok("full")
18 )
19}
20
21#[allow(clippy::print_stderr, reason = "necessary for early logging")]
27pub fn ensure_error<E: AsRef<dyn Error>>(error: E) {
28 if tracing::event_enabled!(Level::ERROR) {
29 crate::error!(error = error.as_ref());
30 } else {
31 eprintln!("error: {}", LogError(error.as_ref()));
32 }
33}
34
35struct LogError<'a, E: Error + ?Sized>(pub &'a E);
37
38impl<E: Error + ?Sized> fmt::Display for LogError<'_, E> {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "{}", self.0)?;
41
42 let mut source = self.0.source();
43 while let Some(s) = source {
44 write!(f, "\n caused by: {s}")?;
45 source = s.source();
46 }
47
48 Ok(())
51 }
52}