Skip to main content

bitrouter_core/
errors.rs

1use crate::models::shared::types::JsonValue;
2use thiserror::Error;
3
4pub type Result<T> = std::result::Result<T, BitrouterError>;
5
6#[derive(Debug, Clone)]
7pub struct ProviderErrorContext {
8    pub status_code: Option<u16>,
9    pub error_type: Option<String>,
10    pub code: Option<String>,
11    pub param: Option<String>,
12    pub request_id: Option<String>,
13    pub body: Option<JsonValue>,
14}
15
16#[derive(Debug, Clone, Error)]
17pub enum BitrouterError {
18    #[error("{provider} does not support {feature}")]
19    UnsupportedFeature {
20        provider: String,
21        feature: String,
22        details: Option<String>,
23    },
24    #[error("request cancelled: {message}")]
25    Cancelled {
26        provider: Option<String>,
27        message: String,
28    },
29    #[error("invalid request: {message}")]
30    InvalidRequest {
31        provider: Option<String>,
32        message: String,
33        body: Option<JsonValue>,
34    },
35    #[error("transport failure: {message}")]
36    Transport {
37        provider: Option<String>,
38        message: String,
39    },
40    #[error("response decode failure: {message}")]
41    ResponseDecode {
42        provider: Option<String>,
43        message: String,
44        body: Option<JsonValue>,
45    },
46    #[error("invalid response: {message}")]
47    InvalidResponse {
48        provider: Option<String>,
49        message: String,
50        body: Option<JsonValue>,
51    },
52    #[error("provider error: {message}")]
53    Provider {
54        provider: String,
55        message: String,
56        context: Box<ProviderErrorContext>,
57    },
58    #[error("stream protocol failure: {message}")]
59    StreamProtocol {
60        provider: Option<String>,
61        message: String,
62        chunk: Option<JsonValue>,
63    },
64}
65
66impl BitrouterError {
67    pub fn cancelled(provider: Option<&str>, message: impl Into<String>) -> Self {
68        Self::Cancelled {
69            provider: provider.map(str::to_owned),
70            message: message.into(),
71        }
72    }
73
74    pub fn unsupported(
75        provider: impl Into<String>,
76        feature: impl Into<String>,
77        details: Option<String>,
78    ) -> Self {
79        Self::UnsupportedFeature {
80            provider: provider.into(),
81            feature: feature.into(),
82            details,
83        }
84    }
85
86    pub fn invalid_request(
87        provider: Option<&str>,
88        message: impl Into<String>,
89        body: Option<JsonValue>,
90    ) -> Self {
91        Self::InvalidRequest {
92            provider: provider.map(str::to_owned),
93            message: message.into(),
94            body,
95        }
96    }
97
98    pub fn transport(provider: Option<&str>, message: impl Into<String>) -> Self {
99        Self::Transport {
100            provider: provider.map(str::to_owned),
101            message: message.into(),
102        }
103    }
104
105    pub fn response_decode(
106        provider: Option<&str>,
107        message: impl Into<String>,
108        body: Option<JsonValue>,
109    ) -> Self {
110        Self::ResponseDecode {
111            provider: provider.map(str::to_owned),
112            message: message.into(),
113            body,
114        }
115    }
116
117    pub fn invalid_response(
118        provider: Option<&str>,
119        message: impl Into<String>,
120        body: Option<JsonValue>,
121    ) -> Self {
122        Self::InvalidResponse {
123            provider: provider.map(str::to_owned),
124            message: message.into(),
125            body,
126        }
127    }
128
129    pub fn provider_error(
130        provider: impl Into<String>,
131        message: impl Into<String>,
132        context: ProviderErrorContext,
133    ) -> Self {
134        Self::Provider {
135            provider: provider.into(),
136            message: message.into(),
137            context: Box::new(context),
138        }
139    }
140
141    pub fn stream_protocol(
142        provider: Option<&str>,
143        message: impl Into<String>,
144        chunk: Option<JsonValue>,
145    ) -> Self {
146        Self::StreamProtocol {
147            provider: provider.map(str::to_owned),
148            message: message.into(),
149            chunk,
150        }
151    }
152}