parse_rs/
error.rs

1use reqwest::header::InvalidHeaderValue;
2// src/error.rs
3use serde_json::Value;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub enum ParseError {
8    #[error("HTTP request failed: {0}")]
9    ReqwestError(#[from] reqwest::Error),
10
11    #[error("URL parsing failed: {0}")]
12    UrlParseError(#[from] url::ParseError),
13
14    #[error("JSON processing error: {0}")]
15    JsonError(#[from] serde_json::Error),
16
17    #[error("JSON deserialization failed: {0}")]
18    JsonDeserializationFailed(String),
19
20    #[error("Parse API error (code {code}): {error}")]
21    ApiError { code: i32, error: String },
22
23    #[error("Object not found: {0}")]
24    ObjectNotFound(String),
25
26    #[error("Invalid input: {0}")]
27    InvalidInput(String),
28
29    #[error("Invalid class name: {0}")]
30    InvalidClassName(String),
31
32    #[error("Invalid session token: {0}")]
33    InvalidSessionToken(String),
34
35    #[error("Session token is missing")]
36    SessionTokenMissing,
37
38    #[error("Master key required: {0}")]
39    MasterKeyRequired(String),
40
41    #[error("Serialization error: {0}")]
42    SerializationError(String),
43
44    #[error("Unexpected response: {0}")]
45    UnexpectedResponse(String),
46
47    #[error("Resource not found: {0}")]
48    NotFound(String),
49
50    #[error("Unknown error: {0}")]
51    Unknown(String),
52
53    #[error("Operation forbidden: {0}")]
54    OperationForbidden(String),
55
56    #[error("Other Parse error (Code: {code}): {message}")]
57    OtherParseError { code: u16, message: String },
58
59    #[error("SDK error: {0}")]
60    SdkError(String),
61
62    #[error("Authentication error: {0}")]
63    AuthenticationError(String),
64
65    #[error("Connection failed: {0}")]
66    ConnectionFailed(String),
67
68    #[error("Invalid query: {0}")]
69    InvalidQuery(String),
70
71    #[error("Duplicate value: {0}")]
72    DuplicateValue(String),
73
74    #[error("Username taken: {0}")]
75    UsernameTaken(String),
76
77    #[error("Email taken: {0}")]
78    EmailTaken(String),
79
80    #[error("Internal server error: {0}")]
81    InternalServerError(String),
82
83    #[error("Invalid header value: {0}")]
84    InvalidHeaderValue(InvalidHeaderValue),
85
86    #[error("Invalid URL: {0}")]
87    InvalidUrl(String),
88}
89
90impl ParseError {
91    /// Creates a `ParseError` from an HTTP status code and a JSON response body.
92    pub(crate) fn from_response(status_code: u16, response_body: Value) -> Self {
93        let error_code = response_body
94            .get("code")
95            .and_then(|v| v.as_u64())
96            .unwrap_or(0) as u16;
97        let error_message = response_body
98            .get("error")
99            .and_then(|v| v.as_str())
100            .unwrap_or("Unknown error")
101            .to_string();
102
103        match error_code {
104            100 => ParseError::ConnectionFailed(format!("({}) {}", error_code, error_message)),
105            101 => ParseError::ObjectNotFound(format!("({}) {}", error_code, error_message)), // Invalid username/password or object not found
106            102 => ParseError::InvalidQuery(format!("({}) {}", error_code, error_message)),
107            111 => ParseError::InvalidInput(format!(
108                "Invalid field type: ({}) {}",
109                error_code, error_message
110            )),
111            119 => ParseError::OperationForbidden(format!(
112                "Missing master key for operation: ({}) {}",
113                error_code, error_message
114            )),
115            137 => ParseError::DuplicateValue(format!("({}) {}", error_code, error_message)),
116            202 => ParseError::UsernameTaken(format!("({}) {}", error_code, error_message)),
117            203 => ParseError::EmailTaken(format!("({}) {}", error_code, error_message)),
118            209 => ParseError::InvalidSessionToken(format!("({}) {}", error_code, error_message)),
119            _ => {
120                if status_code >= 500 {
121                    ParseError::InternalServerError(format!(
122                        "Server error (HTTP {}): ({}) {}",
123                        status_code, error_code, error_message
124                    ))
125                } else if status_code == 401 || status_code == 403 {
126                    ParseError::AuthenticationError(format!(
127                        "Auth error (HTTP {}): ({}) {}",
128                        status_code, error_code, error_message
129                    ))
130                } else if status_code == 404 {
131                    ParseError::ObjectNotFound(format!(
132                        "Not found (HTTP {}): ({}) {}",
133                        status_code, error_code, error_message
134                    ))
135                } else {
136                    ParseError::OtherParseError {
137                        code: error_code,
138                        message: error_message,
139                    }
140                }
141            }
142        }
143    }
144}