mangadex_api/
error.rs

1use std::fmt::Display;
2
3use derive_builder::UninitializedFieldError;
4use mangadex_api_schema::error::RelationshipConversionError;
5
6#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum Error {
9    /// Error when parsing a URL.
10    ///
11    /// This should not happen.
12    #[error("error parsing the URL")]
13    ParseUrlError(#[from] url::ParseError),
14
15    #[error("there was an error from the MangaDex servers (HTTP {0}): {1}")]
16    ServerError(u16, String),
17
18    #[error("failed to send a request to MangaDex: {0:?}")]
19    RequestError(#[from] reqwest::Error),
20
21    #[error("a field is missing when building the request: {0:?}")]
22    UninitializedFieldError(#[from] UninitializedFieldError),
23
24    /// Error when building the request.
25    #[error("failed to build the request: {0:?}")]
26    BuilderError(#[from] BuilderError),
27
28    #[error("missing auth tokens; please log in to MangaDex")]
29    MissingTokens,
30
31    #[error("missing client info; please insert the client_id and client_secret")]
32    MissingClientInfo,
33
34    #[error("missing captcha; please insert it or solve a captcha")]
35    MissingCaptcha,
36
37    #[error("an error occurred while pinging the MangaDex server")]
38    PingError,
39
40    /// Errors returned from the MangaDex API request.
41    #[error("an error occurred with the MangaDex API request: {0:?}")]
42    Api(#[from] mangadex_api_schema::error::MangaDexErrorResponse_),
43
44    /// Error while building the request struct.
45    #[error("failed to build a request: {0}")]
46    RequestBuilderError(String),
47
48    /// Error while parsing the type.
49    #[error("an error occurred while parsing the type: {0}")]
50    ParseError(String),
51
52    #[error("an eccor captured")]
53    Io(#[from] std::io::Error),
54
55    #[error(transparent)]
56    RateLimitParseError(#[from] crate::rate_limit::RateLimitParseError),
57
58    #[error("Rate Limit Excedeed")]
59    RateLimitExcedeed,
60
61    #[error(transparent)]
62    ForumThreadTypeParseError(#[from] mangadex_api_types::forum_thread::ForumThreadTypeParseError),
63
64    #[error(transparent)]
65    RelationshipConversionError(#[from] RelationshipConversionError),
66
67    #[error(transparent)]
68    Types(#[from] mangadex_api_types::error::Error),
69
70    #[error("This file {0} was skipped")]
71    SkippedDownload(String),
72
73    #[error("The API is temporarily anavailable. Reason: {}", if let Some (reason) = .0 {
74        &reason
75    } else {
76        "Unknown"
77    })]
78    ServiceUnavailable(Option<String>),
79
80    #[cfg(feature = "oauth")]
81    #[error("Got Oauth Error response (status: {}, reason: {})", .code, reason.as_ref().map_or("...", |v| v))]
82    OauthError { code: u16, reason: Option<String> },
83
84    #[error("{0}")]
85    UnknowSource(String),
86}
87
88impl Error {
89    pub fn unknow<S>(source: S) -> Self
90    where
91        S: Into<String>,
92    {
93        Self::UnknowSource(source.into())
94    }
95}
96
97impl serde::Serialize for Error {
98    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
99    where
100        S: serde::Serializer,
101    {
102        format!("{self}").serialize(serializer)
103    }
104}
105
106#[derive(Debug)]
107#[non_exhaustive]
108pub enum BuilderError {
109    /// Uninitialized field
110    UninitializedField(String),
111    /// Custom validation error
112    ValidationError(String),
113}
114
115impl From<String> for BuilderError {
116    fn from(value: String) -> Self {
117        Self::ValidationError(value)
118    }
119}
120
121impl From<UninitializedFieldError> for BuilderError {
122    fn from(value: UninitializedFieldError) -> Self {
123        Self::UninitializedField(value.field_name().to_string())
124    }
125}
126impl Display for BuilderError {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        match self {
129            BuilderError::UninitializedField(s) => {
130                f.write_str(format!("the field {s} must initialized").as_str())
131            }
132            BuilderError::ValidationError(s) => f.write_str(s.as_str()),
133        }
134    }
135}
136impl std::error::Error for BuilderError {}