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}