hermes_error/
types.rs

1use alloc::string::{String, ToString};
2use alloc::sync::Arc;
3use core::fmt::{self, Debug, Display, Formatter};
4
5use eyre::{eyre, Report};
6
7pub type HermesError = Error;
8
9#[derive(Clone)]
10pub struct Error {
11    pub is_retryable: bool,
12    pub detail: ErrorDetail,
13}
14
15#[derive(Clone)]
16pub enum ErrorDetail {
17    Report(Arc<Report>),
18    Wrapped(String, Arc<ErrorDetail>),
19}
20
21impl<E> From<E> for Error
22where
23    Report: From<E>,
24{
25    fn from(e: E) -> Self {
26        Self::report(e)
27    }
28}
29
30#[allow(clippy::from_over_into)]
31impl Into<Report> for Error {
32    fn into(self) -> Report {
33        eyre!("{}", self)
34    }
35}
36
37impl Error {
38    pub fn report<E>(e: E) -> Self
39    where
40        Report: From<E>,
41    {
42        Self {
43            is_retryable: false,
44            detail: ErrorDetail::Report(Arc::new(e.into())),
45        }
46    }
47
48    pub fn wrap<M>(self, message: M) -> Self
49    where
50        M: Display,
51    {
52        Self {
53            is_retryable: self.is_retryable,
54            detail: ErrorDetail::Wrapped(message.to_string(), Arc::new(self.detail)),
55        }
56    }
57}
58
59impl Debug for Error {
60    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61        if self.is_retryable {
62            write!(f, "retryable error: ")?;
63        }
64
65        Debug::fmt(&self.detail, f)
66    }
67}
68
69impl Display for Error {
70    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
71        Debug::fmt(self, f)
72    }
73}
74
75impl Debug for ErrorDetail {
76    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
77        match self {
78            ErrorDetail::Report(report) => Debug::fmt(report, f),
79            ErrorDetail::Wrapped(message, detail) => {
80                write!(f, "{}: {:?}", message, detail)
81            }
82        }
83    }
84}