1use s3s::S3Error;
2use s3s::S3ErrorCode;
3use s3s::StdError;
4
5use std::panic::Location;
6
7use tracing::error;
8
9#[derive(Debug)]
10pub struct Error {
11 source: StdError,
12}
13
14pub type Result<T = (), E = Error> = std::result::Result<T, E>;
15
16impl Error {
17 #[must_use]
18 #[track_caller]
19 pub fn new(source: StdError) -> Self {
20 log(&*source);
21 Self { source }
22 }
23
24 #[must_use]
25 #[track_caller]
26 pub fn from_string(s: impl Into<String>) -> Self {
27 Self::new(s.into().into())
28 }
29}
30
31impl<E> From<E> for Error
32where
33 E: std::error::Error + Send + Sync + 'static,
34{
35 #[track_caller]
36 fn from(source: E) -> Self {
37 Self::new(Box::new(source))
38 }
39}
40
41impl From<Error> for S3Error {
42 fn from(e: Error) -> Self {
43 S3Error::with_source(S3ErrorCode::InternalError, e.source)
44 }
45}
46
47#[inline]
48#[track_caller]
49pub(crate) fn log(source: &dyn std::error::Error) {
50 if cfg!(feature = "binary") {
51 let location = Location::caller();
52 let span_trace = tracing_error::SpanTrace::capture();
53
54 error!(
55 target: "s3s_fs_internal_error",
56 %location,
57 error=%source,
58 "span trace:\n{span_trace}"
59 );
60 }
61}
62
63macro_rules! try_ {
64 ($result:expr) => {
65 match $result {
66 Ok(val) => val,
67 Err(err) => {
68 $crate::error::log(&err);
69 return Err(::s3s::S3Error::internal_error(err));
70 }
71 }
72 };
73}