babelforce_manager_sdk/
error.rs1use serde_json::Value;
2
3#[derive(Debug, thiserror::Error)]
5pub enum ManagerError {
6 #[error("manager API error {status}: {message}")]
8 Api {
9 status: u16,
11 code: Option<String>,
13 message: String,
15 body: String,
17 },
18 #[error("network error: {0}")]
20 Network(String),
21 #[error("decode error: {0}")]
23 Decode(String),
24 #[error("invalid argument: {0}")]
26 InvalidArgument(String),
27}
28
29impl ManagerError {
30 pub(crate) fn from_response(status: u16, body: String) -> Self {
33 let mut code = None;
34 let mut message = String::new();
35 if let Ok(v) = serde_json::from_str::<Value>(&body) {
36 code = v.get("code").and_then(Value::as_str).map(str::to_string);
37 for k in ["message", "error", "detail"] {
38 if let Some(m) = v.get(k).and_then(Value::as_str) {
39 if !m.is_empty() {
40 message = m.to_string();
41 break;
42 }
43 }
44 }
45 }
46 if message.is_empty() {
47 message = format!("HTTP {status}");
48 }
49 ManagerError::Api {
50 status,
51 code,
52 message,
53 body,
54 }
55 }
56}
57
58pub(crate) fn map_manager_err<T>(e: crate::gen::manager::apis::Error<T>) -> ManagerError {
64 use crate::gen::manager::apis::Error;
65 match e {
66 Error::ResponseError(rc) => ManagerError::from_response(rc.status.as_u16(), rc.content),
67 Error::Reqwest(err) => ManagerError::Network(err.to_string()),
68 Error::Serde(err) => ManagerError::Decode(err.to_string()),
69 Error::Io(err) => ManagerError::Network(err.to_string()),
70 }
71}
72
73impl<T> crate::retry::Transient for crate::gen::manager::apis::Error<T> {
74 fn transient(&self, idempotent: bool) -> bool {
75 use crate::gen::manager::apis::Error;
76 match self {
77 Error::Reqwest(_) | Error::Io(_) => idempotent,
78 Error::ResponseError(rc) => {
79 let s = rc.status.as_u16();
80 s == 429 || (idempotent && (s == 502 || s == 503 || s == 504))
81 }
82 _ => false,
83 }
84 }
85}
86
87impl crate::retry::Transient for ManagerError {
90 fn transient(&self, idempotent: bool) -> bool {
91 match self {
92 ManagerError::Network(_) => idempotent,
93 ManagerError::Api { status, .. } => {
94 *status == 429 || (idempotent && matches!(status, 502..=504))
95 }
96 _ => false,
97 }
98 }
99}
100
101pub(crate) fn map_user_err<T>(e: crate::gen::user::apis::Error<T>) -> ManagerError {
102 use crate::gen::user::apis::Error;
103 match e {
104 Error::ResponseError(rc) => ManagerError::from_response(rc.status.as_u16(), rc.content),
105 Error::Reqwest(err) => ManagerError::Network(err.to_string()),
106 Error::Serde(err) => ManagerError::Decode(err.to_string()),
107 Error::Io(err) => ManagerError::Network(err.to_string()),
108 }
109}
110
111impl<T> crate::retry::Transient for crate::gen::user::apis::Error<T> {
112 fn transient(&self, idempotent: bool) -> bool {
113 use crate::gen::user::apis::Error;
114 match self {
115 Error::Reqwest(_) | Error::Io(_) => idempotent,
116 Error::ResponseError(rc) => {
117 let s = rc.status.as_u16();
118 s == 429 || (idempotent && (s == 502 || s == 503 || s == 504))
119 }
120 _ => false,
121 }
122 }
123}
124
125pub(crate) fn map_task_automation_err<T>(
126 e: crate::gen::task_automation::apis::Error<T>,
127) -> ManagerError {
128 use crate::gen::task_automation::apis::Error;
129 match e {
130 Error::ResponseError(rc) => ManagerError::from_response(rc.status.as_u16(), rc.content),
131 Error::Reqwest(err) => ManagerError::Network(err.to_string()),
132 Error::Serde(err) => ManagerError::Decode(err.to_string()),
133 Error::Io(err) => ManagerError::Network(err.to_string()),
134 }
135}
136
137impl<T> crate::retry::Transient for crate::gen::task_automation::apis::Error<T> {
138 fn transient(&self, idempotent: bool) -> bool {
139 use crate::gen::task_automation::apis::Error;
140 match self {
141 Error::Reqwest(_) | Error::Io(_) => idempotent,
142 Error::ResponseError(rc) => {
143 let s = rc.status.as_u16();
144 s == 429 || (idempotent && (s == 502 || s == 503 || s == 504))
145 }
146 _ => false,
147 }
148 }
149}
150
151pub(crate) fn map_task_schedule_err<T>(
152 e: crate::gen::task_schedule::apis::Error<T>,
153) -> ManagerError {
154 use crate::gen::task_schedule::apis::Error;
155 match e {
156 Error::ResponseError(rc) => ManagerError::from_response(rc.status.as_u16(), rc.content),
157 Error::Reqwest(err) => ManagerError::Network(err.to_string()),
158 Error::Serde(err) => ManagerError::Decode(err.to_string()),
159 Error::Io(err) => ManagerError::Network(err.to_string()),
160 }
161}
162
163impl<T> crate::retry::Transient for crate::gen::task_schedule::apis::Error<T> {
164 fn transient(&self, idempotent: bool) -> bool {
165 use crate::gen::task_schedule::apis::Error;
166 match self {
167 Error::Reqwest(_) | Error::Io(_) => idempotent,
168 Error::ResponseError(rc) => {
169 let s = rc.status.as_u16();
170 s == 429 || (idempotent && (s == 502 || s == 503 || s == 504))
171 }
172 _ => false,
173 }
174 }
175}
176
177pub(crate) fn map_auth_err<T>(e: crate::gen::auth::apis::Error<T>) -> ManagerError {
178 use crate::gen::auth::apis::Error;
179 match e {
180 Error::ResponseError(rc) => ManagerError::from_response(rc.status.as_u16(), rc.content),
181 Error::Reqwest(err) => ManagerError::Network(err.to_string()),
182 Error::Serde(err) => ManagerError::Decode(err.to_string()),
183 Error::Io(err) => ManagerError::Network(err.to_string()),
184 }
185}
186
187impl<T> crate::retry::Transient for crate::gen::auth::apis::Error<T> {
188 fn transient(&self, idempotent: bool) -> bool {
189 use crate::gen::auth::apis::Error;
190 match self {
191 Error::Reqwest(_) | Error::Io(_) => idempotent,
192 Error::ResponseError(rc) => {
193 let s = rc.status.as_u16();
194 s == 429 || (idempotent && (s == 502 || s == 503 || s == 504))
195 }
196 _ => false,
197 }
198 }
199}