1use reqwest::header::InvalidHeaderValue;
2use 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 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)), 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}