nautilus_tardis/common/
error.rs1#[derive(Debug, thiserror::Error)]
20pub enum TardisError {
21 #[error("HTTP error: {0}")]
23 Http(#[from] crate::http::error::Error),
24
25 #[error("Machine error: {0}")]
27 Machine(#[from] crate::machine::Error),
28}
29
30impl TardisError {
31 #[must_use]
34 pub fn is_retryable(&self) -> bool {
35 match self {
36 Self::Http(crate::http::error::Error::ApiError { status, .. }) => {
37 *status == 429 || *status >= 500
38 }
39 Self::Http(crate::http::error::Error::Request(_)) => true,
40 Self::Machine(crate::machine::Error::ConnectFailed(_)) => true,
41 Self::Machine(crate::machine::Error::ConnectionClosed { reason }) => {
42 !crate::machine::is_unsupported_streaming_error(reason)
43 }
44 _ => false,
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use rstest::rstest;
52
53 use super::*;
54 use crate::{common::enums::TardisExchange, machine::Error};
55
56 #[rstest]
57 #[case(
58 "Error: Real-time streaming is not supported for exchange bitmex",
59 false
60 )]
61 #[case("Real-time streaming is not supported for exchange coinflex", false)]
62 #[case("Too many subsequent errors when connecting to deribit WS API", true)]
63 fn test_machine_close_retryable(#[case] reason: &str, #[case] expected: bool) {
64 let error = TardisError::Machine(Error::ConnectionClosed {
65 reason: reason.to_string(),
66 });
67
68 assert_eq!(error.is_retryable(), expected);
69 }
70
71 #[rstest]
72 fn test_unsupported_streaming_exchange_not_retryable() {
73 let error =
74 TardisError::Machine(Error::UnsupportedStreamingExchange(TardisExchange::Bitmex));
75
76 assert!(!error.is_retryable());
77 }
78}