1use crate::api::v4::models::AggregatedItemError;
4use reqwest::Error as ReqwestError;
5use std::collections::HashMap;
6use std::io;
7use thiserror::Error;
8
9#[derive(Error, Debug)]
11pub enum Error {
12 #[error("HTTP request error: {0}")]
14 Http(#[from] ReqwestError),
15
16 #[error("JSON error: {0}")]
18 Json(#[from] serde_json::Error),
19
20 #[error("IO error: {0}")]
22 Io(#[from] io::Error),
23
24 #[error("API error: {message} (code: {code})")]
26 Api { code: i32, message: String },
27
28 #[error("API error: {message} (code: {code})")]
34 ApiWithData {
35 code: i32,
36 message: String,
37 data: serde_json::Value,
38 },
39
40 #[error("Batch operation partially failed: {} of the submitted item(s) failed", errors.len())]
46 Aggregate {
47 code: i32,
48 message: String,
49 errors: HashMap<String, AggregatedItemError>,
50 },
51
52 #[error("Authentication error: {0}")]
54 Auth(String),
55
56 #[error("Invalid response: {0}")]
58 InvalidResponse(String),
59
60 #[error("Invalid timestamp: {0}")]
62 InvalidTimestamp(String),
63
64 #[error("Feature '{0}' not supported in API {1}")]
66 UnsupportedFeature(String, String),
67
68 #[error("Two-factor authentication required (session ID: {0})")]
71 TwoFactorRequired(String),
72
73 #[error("Unauthorized: {0}")]
75 Unauthorized(String),
76
77 #[error("CAPTCHA required for login")]
79 CaptchaRequired,
80
81 #[error("CAPTCHA validation failed: {0}")]
83 CaptchaInvalid(String),
84}
85
86impl Error {
87 pub fn message(&self) -> Option<&str> {
90 match self {
91 Error::Api { message, .. }
92 | Error::ApiWithData { message, .. }
93 | Error::Aggregate { message, .. } => Some(message),
94 _ => None,
95 }
96 }
97
98 pub fn code(&self) -> Option<i32> {
100 match self {
101 Error::Api { code, .. }
102 | Error::ApiWithData { code, .. }
103 | Error::Aggregate { code, .. } => Some(*code),
104 _ => None,
105 }
106 }
107
108 pub fn data(&self) -> Option<&serde_json::Value> {
110 match self {
111 Error::ApiWithData { data, .. } => Some(data),
112 _ => None,
113 }
114 }
115
116 pub fn aggregated_errors(&self) -> Option<&HashMap<String, AggregatedItemError>> {
118 match self {
119 Error::Aggregate { errors, .. } => Some(errors),
120 _ => None,
121 }
122 }
123}