exc_service/
error.rs

1use std::convert::Infallible;
2
3use thiserror::Error;
4
5/// Instrument Errors.
6#[derive(Debug, Error)]
7pub enum InstrumentError {
8    /// Instrument does not exist.
9    #[error("instrument does not exist")]
10    NotFound,
11}
12
13/// Exchange Errors.
14#[derive(Debug, Error)]
15pub enum ExchangeError {
16    /// Error from layers.
17    #[error("layer: {0}")]
18    Layer(#[from] Box<dyn std::error::Error + Send + Sync>),
19    #[cfg(feature = "http")]
20    /// Http errors.
21    #[error("http: {0}")]
22    Http(hyper::Error),
23    /// All other errors.
24    #[error(transparent)]
25    Other(#[from] anyhow::Error),
26    /// All other api errors.
27    #[error("api: {0}")]
28    Api(anyhow::Error),
29    /// Unavailable.
30    #[error("unavailable: {0}")]
31    Unavailable(anyhow::Error),
32    /// Instrument errors.
33    #[error("instrument: {0}")]
34    Instrument(InstrumentError),
35    /// Rate limited.
36    #[error("rate limited: {0}")]
37    RateLimited(anyhow::Error),
38    /// API Key error.
39    #[error("key error: {0}")]
40    KeyError(anyhow::Error),
41    /// Order not found.
42    #[error("order not found")]
43    OrderNotFound,
44    /// Forbidden.
45    #[error("forbidden: {0}")]
46    Forbidden(anyhow::Error),
47    /// Unexpected response type.
48    #[error("unexpected response type: {0}")]
49    UnexpectedResponseType(String),
50}
51
52impl ExchangeError {
53    /// Is temporary.
54    pub fn is_temporary(&self) -> bool {
55        #[cfg(feature = "http")]
56        {
57            matches!(
58                self,
59                Self::RateLimited(_) | Self::Unavailable(_) | Self::Http(_)
60            )
61        }
62        #[cfg(not(feature = "http"))]
63        {
64            matches!(self, Self::RateLimited(_) | Self::Unavailable(_))
65        }
66    }
67
68    /// Flatten.
69    pub fn flatten(self) -> Self {
70        match self {
71            Self::Layer(err) => match err.downcast::<Self>() {
72                Ok(err) => (*err).flatten(),
73                Err(err) => Self::Other(anyhow::anyhow!("{err}")),
74            },
75            err => err,
76        }
77    }
78
79    /// Flatten layered error.
80    pub fn layer(err: Box<dyn std::error::Error + Send + Sync>) -> Self {
81        match err.downcast::<Self>() {
82            Ok(err) => (*err).flatten(),
83            Err(err) => Self::Other(anyhow::anyhow!("{err}")),
84        }
85    }
86
87    /// Unexpected response type.
88    pub fn unexpected_response_type(msg: impl ToString) -> Self {
89        Self::UnexpectedResponseType(msg.to_string())
90    }
91}
92
93impl From<Infallible> for ExchangeError {
94    fn from(_: Infallible) -> Self {
95        panic!("infallible")
96    }
97}