use s3s::S3Error; use s3s::S3ErrorCode; use s3s::StdError; use std::fmt::Display; use std::panic::Location; use tracing::error; #[derive(Debug)] pub struct Error { source: StdError, } pub type Result = std::result::Result; impl Error { #[must_use] #[track_caller] pub fn new(source: StdError) -> Self { log(&*source); Self { source } } #[must_use] #[track_caller] pub fn from_string(s: impl Into) -> Self { Self::new(s.into().into()) } } impl From for Error where E: std::error::Error + Send + Sync + 'static, { #[track_caller] fn from(source: E) -> Self { Self::new(Box::new(source)) } } impl From for S3Error { fn from(e: Error) -> Self { S3Error::with_source(S3ErrorCode::InternalError, e.source) } } impl Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.source.fmt(f) } } #[inline] #[track_caller] pub(crate) fn log(source: &dyn std::error::Error) { if cfg!(feature = "binary") { let location = Location::caller(); let span_trace = tracing_error::SpanTrace::capture(); error!( target: "s3s_fs_internal_error", %location, error=%source, "span trace:\n{span_trace}" ); } } macro_rules! try_ { ($result:expr) => { match $result { Ok(val) => val, Err(err) => { $crate::error::log(&err); return Err(::s3s::S3Error::internal_error(err)); } } }; }