1use serde::{Deserialize, Serialize};
2use thiserror::Error as ThisError;
3
4#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, ThisError, Debug)]
5pub enum HttpError {
6 #[error("HTTP error {code}: {message}")]
7 #[serde(skip)]
8 Http {
9 code: http_types::StatusCode,
10 message: String,
11 body: Option<Vec<u8>>,
12 },
13 #[error("JSON serialisation error: {0}")]
14 #[serde(skip)]
15 Json(String),
16 #[error("URL parse error: {0}")]
17 Url(String),
18 #[error("IO error: {0}")]
19 Io(String),
20 #[error("Timeout")]
21 Timeout,
22}
23
24impl From<http_types::Error> for HttpError {
25 fn from(e: http_types::Error) -> Self {
26 HttpError::Http {
27 code: e.status(),
28 message: e.to_string(),
29 body: None,
30 }
31 }
32}
33
34impl From<serde_json::Error> for HttpError {
35 fn from(e: serde_json::Error) -> Self {
36 HttpError::Json(e.to_string())
37 }
38}
39
40impl From<url::ParseError> for HttpError {
41 fn from(e: url::ParseError) -> Self {
42 HttpError::Url(e.to_string())
43 }
44}
45
46impl From<serde_qs::Error> for HttpError {
47 fn from(e: serde_qs::Error) -> Self {
48 HttpError::Json(e.to_string())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_error_display() {
58 let error = HttpError::Http {
59 code: http_types::StatusCode::BadRequest,
60 message: "Bad Request".to_string(),
61 body: None,
62 };
63 assert_eq!(error.to_string(), "HTTP error 400: Bad Request");
64 }
65}