pokemon_tcg_sdk/
errors.rs

1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5pub enum ClientError {
6    /// The request was unacceptable, often due to an incorrect query string parameter
7    #[error("Bad Request: {}", .0.error.message)]
8    BadRequest(ErrorEnvelope),
9    /// The parameters were valid but the request failed.
10    #[error("Request Failed: {}", .0.error.message)]
11    RequestFailed(ErrorEnvelope),
12    /// The user doesn't have permissions to perform the request.
13    #[error("Request Forbidden: {}", .0.error.message)]
14    Forbidden(ErrorEnvelope),
15    /// The requested resource doesn't exist.
16    #[error("Not Found: {}", .0.error.message)]
17    NotFound(ErrorEnvelope),
18    /// The rate limit has been exceeded.
19    #[error("Too Many Requests: {}", .0.error.message)]
20    TooManyRequests(ErrorEnvelope),
21    /// Something went wrong on our end.
22    #[error("Server Error: {}", .0.error.message)]
23    ServerError(ErrorEnvelope),
24    /// Error parsing the response body
25    #[error("Failed to decode the response body")]
26    DecodeFailed(#[source] reqwest::Error),
27    /// Error occurred before the body could be decoded
28    #[error("An error occurred while attempting to make a request.")]
29    RequestError(#[source] reqwest::Error),
30    #[error("An error occurred while constructing the client.")]
31    ConstructionFailed(#[source] reqwest::Error),
32    #[error("The API key is invalid.")]
33    InvalidApiKey(#[source] reqwest::header::InvalidHeaderValue),
34}
35
36/// The root response body for an error
37#[derive(Debug, Serialize, Deserialize)]
38pub struct ErrorEnvelope {
39    pub error: ApiError,
40}
41
42/// The details of an error response
43#[derive(Debug, Serialize, Deserialize)]
44pub struct ApiError {
45    pub message: String,
46    pub code: usize,
47}
48
49impl From<ErrorEnvelope> for ClientError {
50    fn from(e: ErrorEnvelope) -> Self {
51        match e.error.code {
52            400 => ClientError::BadRequest(e),
53            402 => ClientError::RequestFailed(e),
54            403 => ClientError::Forbidden(e),
55            404 => ClientError::NotFound(e),
56            429 => ClientError::TooManyRequests(e),
57            500..=504 => ClientError::ServerError(e),
58            _ => ClientError::BadRequest(e),
59        }
60    }
61}
62
63impl From<reqwest::Error> for ClientError {
64    fn from(e: reqwest::Error) -> Self {
65        if e.is_builder() {
66            return ClientError::ConstructionFailed(e);
67        }
68
69        ClientError::RequestError(e)
70    }
71}
72
73impl From<reqwest::header::InvalidHeaderValue> for ClientError {
74    fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
75        ClientError::InvalidApiKey(e)
76    }
77}