tmdb_api/
error.rs

1#[derive(Debug, Deserialize, Serialize)]
2pub struct ServerOtherBodyError {
3    pub status_code: u16,
4    pub status_message: String,
5}
6
7impl std::error::Error for ServerOtherBodyError {}
8impl std::fmt::Display for ServerOtherBodyError {
9    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10        write!(
11            f,
12            "server body error with code {}: {}",
13            self.status_code, self.status_message
14        )
15    }
16}
17
18#[derive(Debug, Deserialize, Serialize)]
19pub struct ServerValidationBodyError {
20    pub errors: Vec<String>,
21}
22
23impl std::error::Error for ServerValidationBodyError {}
24impl std::fmt::Display for ServerValidationBodyError {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        write!(f, "server validation body errors:")?;
27        for item in self.errors.iter() {
28            write!(f, ", {item}")?;
29        }
30        Ok(())
31    }
32}
33
34#[derive(Debug, Deserialize, Serialize, thiserror::Error)]
35#[serde(untagged)]
36pub enum ServerBodyError {
37    #[error(transparent)]
38    Other(#[from] ServerOtherBodyError),
39    #[error(transparent)]
40    Validation(#[from] ServerValidationBodyError),
41}
42
43impl ServerBodyError {
44    pub fn as_other_error(&self) -> Option<&ServerOtherBodyError> {
45        match self {
46            Self::Other(inner) => Some(inner),
47            _ => None,
48        }
49    }
50
51    pub fn as_validation_error(&self) -> Option<&ServerValidationBodyError> {
52        match self {
53            Self::Validation(inner) => Some(inner),
54            _ => None,
55        }
56    }
57}
58
59#[derive(Debug)]
60pub struct ServerError {
61    pub code: u16,
62    pub body: ServerBodyError,
63}
64
65impl std::fmt::Display for ServerError {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "server error with code {}: {}", self.code, self.body)
68    }
69}
70
71impl std::error::Error for ServerError {
72    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
73        Some(&self.body)
74    }
75}
76
77#[derive(Debug, thiserror::Error)]
78pub enum Error {
79    #[error("couldn't execute request")]
80    Request {
81        #[source]
82        source: Box<dyn std::error::Error + Send>,
83    },
84    #[error("couldn't read response")]
85    Response {
86        #[source]
87        source: Box<dyn std::error::Error + Send>,
88    },
89    #[error(transparent)]
90    Validation(ServerValidationBodyError),
91    #[error("internal server error with code {code}")]
92    Server {
93        code: u16,
94        #[source]
95        content: ServerOtherBodyError,
96    },
97}
98
99impl Error {
100    pub fn as_validation_error(&self) -> Option<&ServerValidationBodyError> {
101        match self {
102            Self::Validation(inner) => Some(inner),
103            _ => None,
104        }
105    }
106
107    pub fn as_server_error(&self) -> Option<&ServerOtherBodyError> {
108        match self {
109            Self::Server { code: _, content } => Some(content),
110            _ => None,
111        }
112    }
113}