1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ErrorBody {
6 pub code: String,
7 #[serde(rename = "type")]
8 pub error_type: String,
9 pub message: String,
10}
11
12impl std::fmt::Display for ErrorBody {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 write!(
15 f,
16 "{} - {} (type: {})",
17 self.code, self.message, self.error_type
18 )
19 }
20}
21
22#[derive(Debug, thiserror::Error)]
24pub enum Error {
25 #[error("API error: {body} (http_status: {status})")]
26 Api { status: u16, body: ErrorBody },
27
28 #[error("HTTP error: {0}")]
29 Http(#[from] reqwest::Error),
30
31 #[error("Invalid config: {0}")]
32 InvalidConfig(String),
33}
34
35pub fn is_not_found(err: &Error) -> bool {
37 matches!(err, Error::Api { status: 404, .. })
38}
39
40pub fn is_rate_limited(err: &Error) -> bool {
42 matches!(err, Error::Api { status: 429, .. })
43}
44
45pub fn is_auth_error(err: &Error) -> bool {
47 matches!(
48 err,
49 Error::Api {
50 status: 401 | 403,
51 ..
52 }
53 )
54}