1use http::{header::InvalidHeaderValue, StatusCode};
4
5#[derive(Debug, thiserror::Error)]
6pub enum ApiError {
7 #[error("Bad Request")]
8 BadRequest,
9 #[error("Unauthorized")]
10 Unauthorized,
11 #[error("Forbidden")]
12 Forbidden,
13 #[error("Not Found")]
14 NotFound,
15 #[error("Resource Already Exists")]
16 AlreadyExists,
17 #[error("Resource Expired")]
18 Expired,
19 #[error("Invalid Content-Type")]
20 InvalidContentType,
21 #[error("User denied the request")]
22 Denied,
23 #[error("Account limit exceeded")]
24 AccountLimitExceeded,
25 #[error("Validation Error")]
26 ValidationError,
27 #[error("Locked User Account")]
28 LockedUserAccount,
29 #[error("VIP Only")]
30 VipOnly,
31 #[error("Rate Limit Exceeded")]
32 RateLimitExceeded,
33 #[error("Server Error")]
34 ServerError,
35 #[error("Service Unavailable")]
36 ServiceUnavailable,
37 #[error("Cloudflare Error")]
38 CloudflareError,
39 #[error("Unknown Error: {0}")]
40 UnknownError(StatusCode),
41}
42
43impl From<StatusCode> for ApiError {
44 fn from(value: StatusCode) -> Self {
45 match value.as_u16() {
46 400 => Self::BadRequest,
47 401 => Self::Unauthorized,
48 403 => Self::Forbidden,
49 404 => Self::NotFound,
50 409 => Self::AlreadyExists,
51 410 => Self::Expired,
52 412 => Self::InvalidContentType,
53 418 => Self::Denied,
54 420 => Self::AccountLimitExceeded,
55 422 => Self::ValidationError,
56 423 => Self::LockedUserAccount,
57 426 => Self::VipOnly,
58 429 => Self::RateLimitExceeded,
59 500 => Self::ServerError,
60 502..=504 => Self::ServiceUnavailable,
61 520..=522 => Self::CloudflareError,
62 _ => Self::UnknownError(value),
63 }
64 }
65}
66
67#[derive(Debug, thiserror::Error)]
69pub enum IntoHttpError {
70 #[error("JSON Error: {0}")]
71 Json(#[from] serde_json::Error),
72 #[error("Invalid Header Value: {0}")]
73 Header(#[from] InvalidHeaderValue),
74 #[error("HTTP Error: {0}")]
75 Http(#[from] http::Error),
76 #[error("Url params error: {0}")]
77 UrlParams(#[from] UrlError),
78 #[error("Query params error: {0}")]
79 QueryParams(#[from] serde_urlencoded::ser::Error),
80 #[error("Missing oauth token")]
81 MissingToken,
82 #[error("Validation Error: {0}")]
83 Validation(String),
84}
85
86#[derive(Debug, thiserror::Error)]
87pub enum FromHttpError {
88 #[error("API Error: {0}")]
89 Api(#[from] ApiError),
90 #[error("Deserialize Error: {0}")]
91 Deserialize(#[from] DeserializeError),
92}
93
94#[derive(Debug, thiserror::Error)]
95pub enum DeserializeError {
96 #[error("JSON Error: {0}")]
97 Json(#[from] serde_json::Error),
98 #[error("Header Error: {0}")]
99 Header(#[from] HeaderError),
100 #[error("Integer Parse Error: {0}")]
101 ParseInt(#[from] std::num::ParseIntError),
102}
103
104#[derive(Debug, thiserror::Error)]
105pub enum HeaderError {
106 #[error("Invalid Header Value: {0}")]
107 ToStrError(#[from] http::header::ToStrError),
108 #[error("Missing Header")]
109 MissingHeader,
110}
111
112#[derive(Debug, PartialEq, Eq, thiserror::Error)]
113pub enum UrlError {
114 #[error("{0}")]
115 Message(String),
116 #[error("Top level serializer only supports structs")]
117 TopLevel,
118 #[error("Invalid endpoint")]
119 InvalidEndpoint,
120 #[error("Value not supported")]
121 ValueNotSupported,
122 #[error("Key not found: {0}")]
123 KeyNotFound(&'static str),
124 #[error("Unfilled field: {0}")]
125 UnfilledField(String),
126}
127
128impl serde::ser::Error for UrlError {
129 fn custom<T: std::fmt::Display>(msg: T) -> Self {
130 Self::Message(msg.to_string())
131 }
132}