1use std::fmt::Display;
2
3use thiserror::Error;
4
5#[derive(Debug, Default)]
20#[cfg_attr(feature = "serde-support", derive(serde::Serialize, serde::Deserialize))]
21#[cfg_attr(feature = "serde-camelcase", serde(rename_all = "camelCase"))]
22pub struct ErrorResponse {
23 pub code: String,
24 pub message: String,
25 pub request_id: String,
26 pub host_id: String,
27 pub ec: String,
28 pub recommend_doc: String,
29}
30
31impl ErrorResponse {
32 pub fn from_xml(xml_content: &str) -> crate::Result<Self> {
33 let mut reader = quick_xml::Reader::from_str(xml_content);
34 let mut ret = Self::default();
35
36 let mut current_tag = String::new();
37
38 loop {
39 match reader.read_event()? {
40 quick_xml::events::Event::Eof => break,
41
42 quick_xml::events::Event::Start(e) => {
43 current_tag = String::from_utf8_lossy(e.local_name().as_ref()).to_string();
44 }
45
46 quick_xml::events::Event::Text(t) => match current_tag.as_str() {
47 "Code" => ret.code = String::from_utf8_lossy(t.as_ref()).to_string(),
48 "Message" => ret.message = String::from_utf8_lossy(t.as_ref()).to_string(),
49 "RequestId" => ret.request_id = String::from_utf8_lossy(t.as_ref()).to_string(),
50 "HostId" => ret.host_id = String::from_utf8_lossy(t.as_ref()).to_string(),
51 "EC" => ret.ec = String::from_utf8_lossy(t.as_ref()).to_string(),
52 "RecommendDoc" => ret.recommend_doc = String::from_utf8_lossy(t.as_ref()).to_string(),
53 _ => {}
54 },
55
56 quick_xml::events::Event::End(_) => {
57 current_tag.clear();
58 }
59
60 _ => {}
61 }
62 }
63
64 Ok(ret)
65 }
66}
67
68impl Display for ErrorResponse {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 write!(f, "Code: {}, Message: {}, Request Id: {}", self.code, self.message, self.request_id)
71 }
72}
73
74#[derive(Error, Debug)]
75pub enum Error {
76 #[error("{0}")]
77 InvalidHeaderName(#[from] reqwest::header::InvalidHeaderName),
78
79 #[error("{0}")]
80 InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue),
81
82 #[error("{0}")]
83 UrlParseError(#[from] url::ParseError),
84
85 #[error("{0}")]
86 ReqwestError(#[from] reqwest::Error),
87
88 #[error("{0}")]
89 XmlParseError(#[from] quick_xml::Error),
90
91 #[error("{0}")]
92 ApiError(Box<ErrorResponse>),
93
94 #[error("{0}")]
95 IoError(#[from] std::io::Error),
96
97 #[error("{0}")]
98 FromUtf8Error(#[from] std::string::FromUtf8Error),
99
100 #[error("{0}")]
101 ParseIntError(#[from] std::num::ParseIntError),
102
103 #[error("{0}")]
104 StatusError(reqwest::StatusCode),
105
106 #[error("{0}")]
107 SerdeJsonError(#[from] serde_json::Error),
108
109 #[error("{0}")]
110 DecodeError(#[from] base64::DecodeError),
111
112 #[error("{0}")]
113 Other(String),
114}