summaryrefslogtreecommitdiff
path: root/trakt-core/src/error.rs
blob: 37a430a99a7984b3868621e34a17f8060a82b7fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Error types for the API.

use http::{header::InvalidHeaderValue, StatusCode};

#[derive(Debug, thiserror::Error)]
pub enum ApiError {
    #[error("Bad Request")]
    BadRequest,
    #[error("Unauthorized")]
    Unauthorized,
    #[error("Forbidden")]
    Forbidden,
    #[error("Not Found")]
    NotFound,
    #[error("Resource Already Exists")]
    AlreadyExists,
    #[error("Resource Expired")]
    Expired,
    #[error("Invalid Content-Type")]
    InvalidContentType,
    #[error("User denied the request")]
    Denied,
    #[error("Account limit exceeded")]
    AccountLimitExceeded,
    #[error("Validation Error")]
    ValidationError,
    #[error("Locked User Account")]
    LockedUserAccount,
    #[error("VIP Only")]
    VipOnly,
    #[error("Rate Limit Exceeded")]
    RateLimitExceeded,
    #[error("Server Error")]
    ServerError,
    #[error("Service Unavailable")]
    ServiceUnavailable,
    #[error("Cloudflare Error")]
    CloudflareError,
    #[error("Unknown Error: {0}")]
    UnknownError(StatusCode),
}

impl From<StatusCode> for ApiError {
    fn from(value: StatusCode) -> Self {
        match value.as_u16() {
            400 => Self::BadRequest,
            401 => Self::Unauthorized,
            403 => Self::Forbidden,
            404 => Self::NotFound,
            409 => Self::AlreadyExists,
            410 => Self::Expired,
            412 => Self::InvalidContentType,
            418 => Self::Denied,
            420 => Self::AccountLimitExceeded,
            422 => Self::ValidationError,
            423 => Self::LockedUserAccount,
            426 => Self::VipOnly,
            429 => Self::RateLimitExceeded,
            500 => Self::ServerError,
            502..=504 => Self::ServiceUnavailable,
            520..=522 => Self::CloudflareError,
            _ => Self::UnknownError(value),
        }
    }
}

/// Error type for converting a request into an HTTP request.
#[derive(Debug, thiserror::Error)]
pub enum IntoHttpError {
    #[error("JSON Error: {0}")]
    Json(#[from] serde_json::Error),
    #[error("Invalid Header Value: {0}")]
    Header(#[from] InvalidHeaderValue),
    #[error("HTTP Error: {0}")]
    Http(#[from] http::Error),
    #[error("Url params error: {0}")]
    UrlParams(#[from] UrlError),
    #[error("Query params error: {0}")]
    QueryParams(#[from] serde_urlencoded::ser::Error),
    #[error("Missing oauth token")]
    MissingToken,
    #[error("Validation Error: {0}")]
    Validation(String),
}

#[derive(Debug, thiserror::Error)]
pub enum FromHttpError {
    #[error("API Error: {0}")]
    Api(#[from] ApiError),
    #[error("Deserialize Error: {0}")]
    Deserialize(#[from] DeserializeError),
}

#[derive(Debug, thiserror::Error)]
pub enum DeserializeError {
    #[error("JSON Error: {0}")]
    Json(#[from] serde_json::Error),
    #[error("Header Error: {0}")]
    Header(#[from] HeaderError),
    #[error("Integer Parse Error: {0}")]
    ParseInt(#[from] std::num::ParseIntError),
}

#[derive(Debug, thiserror::Error)]
pub enum HeaderError {
    #[error("Invalid Header Value: {0}")]
    ToStrError(#[from] http::header::ToStrError),
    #[error("Missing Header")]
    MissingHeader,
}

#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum UrlError {
    #[error("{0}")]
    Message(String),
    #[error("Top level serializer only supports structs")]
    TopLevel,
    #[error("Invalid endpoint")]
    InvalidEndpoint,
    #[error("Value not supported")]
    ValueNotSupported,
    #[error("Key not found: {0}")]
    KeyNotFound(&'static str),
    #[error("Unfilled field: {0}")]
    UnfilledField(String),
}

impl serde::ser::Error for UrlError {
    fn custom<T: std::fmt::Display>(msg: T) -> Self {
        Self::Message(msg.to_string())
    }
}