1use serde::Deserialize;
2use std::collections::HashMap;
3
4pub type FlowResult<T> = Result<T, FlowError>;
5
6#[derive(Debug, thiserror::Error)]
7pub enum FlowError {
8 #[error("flow: authentication failed — {message}")]
9 Authentication { message: String, code: String },
10
11 #[error("flow: resource not found — {message}")]
12 NotFound { message: String, code: String },
13
14 #[error("flow: validation error — {message}")]
15 Validation {
16 message: String,
17 code: String,
18 errors: Vec<HashMap<String, String>>,
19 },
20
21 #[error("flow: rate limited — retry after {retry_after}s")]
22 RateLimit {
23 message: String,
24 code: String,
25 retry_after: f64,
26 },
27
28 #[error("flow: server error — {message}")]
29 Server { message: String, code: String },
30
31 #[error("flow: {message}")]
32 Api { message: String, code: String, status: u16 },
33
34 #[error("flow: network error — {0}")]
35 Network(#[from] reqwest::Error),
36
37 #[error("flow: invalid webhook signature — {0}")]
38 InvalidSignature(String),
39
40 #[error("flow: {0}")]
41 Other(String),
42}
43
44#[derive(Deserialize, Default)]
45pub(crate) struct ErrorBody {
46 pub detail: Option<String>,
47 pub message: Option<String>,
48 pub error: Option<String>,
49 pub code: Option<String>,
50 #[serde(default)]
51 pub errors: Vec<HashMap<String, String>>,
52}
53
54impl ErrorBody {
55 pub fn msg(&self) -> String {
56 self.detail
57 .clone()
58 .or_else(|| self.message.clone())
59 .or_else(|| self.error.clone())
60 .unwrap_or_default()
61 }
62}