1use std::{
2 any::Any,
3 collections::BTreeMap,
4 fmt::{self, Debug, Display, Formatter},
5 marker::PhantomData,
6 sync::Arc,
7};
8
9use serde::{Deserialize, Serialize};
10use thiserror::Error;
11
12use crate::{InputType, Pos, Value, parser};
13
14#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
16#[serde(transparent)]
17pub struct ErrorExtensionValues(BTreeMap<String, Value>);
18
19impl ErrorExtensionValues {
20 pub fn set(&mut self, name: impl AsRef<str>, value: impl Into<Value>) {
22 self.0.insert(name.as_ref().to_string(), value.into());
23 }
24
25 pub fn unset(&mut self, name: impl AsRef<str>) {
27 self.0.remove(name.as_ref());
28 }
29
30 pub fn get(&self, name: impl AsRef<str>) -> Option<&Value> {
32 self.0.get(name.as_ref())
33 }
34}
35
36#[derive(Clone, Serialize, Deserialize)]
38pub struct ServerError {
39 pub message: String,
41 #[serde(skip)]
43 pub source: Option<Arc<dyn Any + Send + Sync>>,
44 #[serde(skip_serializing_if = "Vec::is_empty", default)]
46 pub locations: Vec<Pos>,
47 #[serde(skip_serializing_if = "Vec::is_empty", default)]
49 pub path: Vec<PathSegment>,
50 #[serde(skip_serializing_if = "error_extensions_is_empty", default)]
52 pub extensions: Option<ErrorExtensionValues>,
53}
54
55fn error_extensions_is_empty(values: &Option<ErrorExtensionValues>) -> bool {
56 values.as_ref().is_none_or(|values| values.0.is_empty())
57}
58
59impl Debug for ServerError {
60 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61 f.debug_struct("ServerError")
62 .field("message", &self.message)
63 .field("locations", &self.locations)
64 .field("path", &self.path)
65 .field("extensions", &self.extensions)
66 .finish()
67 }
68}
69
70impl PartialEq for ServerError {
71 fn eq(&self, other: &Self) -> bool {
72 self.message.eq(&other.message)
73 && self.locations.eq(&other.locations)
74 && self.path.eq(&other.path)
75 && self.extensions.eq(&other.extensions)
76 }
77}
78
79impl ServerError {
80 pub fn new(message: impl Into<String>, pos: Option<Pos>) -> Self {
82 Self {
83 message: message.into(),
84 source: None,
85 locations: pos.map(|pos| vec![pos]).unwrap_or_default(),
86 path: Vec::new(),
87 extensions: None,
88 }
89 }
90
91 pub fn source<T: Any + Send + Sync>(&self) -> Option<&T> {
122 self.source.as_ref().map(|err| err.downcast_ref()).flatten()
123 }
124
125 #[doc(hidden)]
126 #[must_use]
127 pub fn with_path(self, path: Vec<PathSegment>) -> Self {
128 Self { path, ..self }
129 }
130}
131
132impl Display for ServerError {
133 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
134 f.write_str(&self.message)
135 }
136}
137
138impl From<ServerError> for Vec<ServerError> {
139 fn from(single: ServerError) -> Self {
140 vec![single]
141 }
142}
143
144impl From<parser::Error> for ServerError {
145 fn from(e: parser::Error) -> Self {
146 Self {
147 message: e.to_string(),
148 source: None,
149 locations: e.positions().collect(),
150 path: Vec::new(),
151 extensions: None,
152 }
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
161#[serde(untagged)]
162pub enum PathSegment {
163 Field(String),
165 Index(usize),
167}
168
169pub type ServerResult<T> = std::result::Result<T, ServerError>;
171
172#[derive(Debug)]
177pub struct InputValueError<T> {
178 message: String,
179 extensions: Option<ErrorExtensionValues>,
180 phantom: PhantomData<T>,
181}
182
183impl<T: InputType> InputValueError<T> {
184 fn new(message: String, extensions: Option<ErrorExtensionValues>) -> Self {
185 Self {
186 message,
187 extensions,
188 phantom: PhantomData,
189 }
190 }
191
192 #[must_use]
194 pub fn expected_type(actual: Value) -> Self {
195 Self::new(
196 format!(
197 r#"Expected input type "{}", found {}."#,
198 T::type_name(),
199 actual
200 ),
201 None,
202 )
203 }
204
205 #[must_use]
210 pub fn custom(msg: impl Display) -> Self {
211 Self::new(
212 format!(r#"Failed to parse "{}": {}"#, T::type_name(), msg),
213 None,
214 )
215 }
216
217 pub fn propagate<U: InputType>(self) -> InputValueError<U> {
219 if T::type_name() != U::type_name() {
220 InputValueError::new(
221 format!(
222 r#"{} (occurred while parsing "{}")"#,
223 self.message,
224 U::type_name()
225 ),
226 self.extensions,
227 )
228 } else {
229 InputValueError::new(self.message, self.extensions)
230 }
231 }
232
233 pub fn with_extension(mut self, name: impl AsRef<str>, value: impl Into<Value>) -> Self {
235 self.extensions
236 .get_or_insert_with(ErrorExtensionValues::default)
237 .set(name, value);
238 self
239 }
240
241 pub fn into_server_error(self, pos: Pos) -> ServerError {
243 let mut err = ServerError::new(self.message, Some(pos));
244 err.extensions = self.extensions;
245 err
246 }
247}
248
249impl<T: InputType, E: Display> From<E> for InputValueError<T> {
250 fn from(error: E) -> Self {
251 Self::custom(error)
252 }
253}
254
255pub type InputValueResult<T> = Result<T, InputValueError<T>>;
257
258#[derive(Clone, Serialize)]
260pub struct Error {
261 pub message: String,
263 #[serde(skip)]
265 pub source: Option<Arc<dyn Any + Send + Sync>>,
266 #[serde(skip_serializing_if = "error_extensions_is_empty")]
268 pub extensions: Option<ErrorExtensionValues>,
269}
270
271impl Debug for Error {
272 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
273 f.debug_struct("Error")
274 .field("message", &self.message)
275 .field("extensions", &self.extensions)
276 .finish()
277 }
278}
279
280impl PartialEq for Error {
281 fn eq(&self, other: &Self) -> bool {
282 self.message.eq(&other.message) && self.extensions.eq(&other.extensions)
283 }
284}
285
286impl Error {
287 pub fn new(message: impl Into<String>) -> Self {
289 Self {
290 message: message.into(),
291 source: None,
292 extensions: None,
293 }
294 }
295
296 pub fn new_with_source(source: impl Display + Send + Sync + 'static) -> Self {
299 Self {
300 message: source.to_string(),
301 source: Some(Arc::new(source)),
302 extensions: None,
303 }
304 }
305
306 #[must_use]
308 pub fn into_server_error(self, pos: Pos) -> ServerError {
309 ServerError {
310 message: self.message,
311 source: self.source,
312 locations: vec![pos],
313 path: Vec::new(),
314 extensions: self.extensions,
315 }
316 }
317}
318
319impl<T: Display + Send + Sync + 'static> From<T> for Error {
320 fn from(e: T) -> Self {
321 Self {
322 message: e.to_string(),
323 source: Some(Arc::new(e)),
324 extensions: None,
325 }
326 }
327}
328
329pub type Result<T, E = Error> = std::result::Result<T, E>;
331
332#[derive(Debug, Error)]
334#[non_exhaustive]
335pub enum ParseRequestError {
336 #[error("{0}")]
338 Io(#[from] std::io::Error),
339
340 #[error("Invalid request: {0}")]
342 InvalidRequest(Box<dyn std::error::Error + Send + Sync>),
343
344 #[error("Invalid files map: {0}")]
346 InvalidFilesMap(Box<dyn std::error::Error + Send + Sync>),
347
348 #[error("Invalid multipart data")]
350 InvalidMultipart(multer::Error),
351
352 #[error("Missing \"operators\" part")]
354 MissingOperatorsPart,
355
356 #[error("Missing \"map\" part")]
358 MissingMapPart,
359
360 #[error("It's not an upload operation")]
362 NotUpload,
363
364 #[error("Missing files")]
366 MissingFiles,
367
368 #[error("Payload too large")]
370 PayloadTooLarge,
371
372 #[error("Batch requests are not supported")]
375 UnsupportedBatch,
376}
377
378impl From<multer::Error> for ParseRequestError {
379 fn from(err: multer::Error) -> Self {
380 match err {
381 multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => {
382 ParseRequestError::PayloadTooLarge
383 }
384 _ => ParseRequestError::InvalidMultipart(err),
385 }
386 }
387}
388
389impl From<mime::FromStrError> for ParseRequestError {
390 fn from(e: mime::FromStrError) -> Self {
391 Self::InvalidRequest(Box::new(e))
392 }
393}
394
395pub trait ErrorExtensions: Sized {
397 fn extend(&self) -> Error;
399
400 fn extend_with<C>(self, cb: C) -> Error
402 where
403 C: FnOnce(&Self, &mut ErrorExtensionValues),
404 {
405 let mut new_extensions = Default::default();
406 cb(&self, &mut new_extensions);
407
408 let Error {
409 message,
410 source,
411 extensions,
412 } = self.extend();
413
414 let mut extensions = extensions.unwrap_or_default();
415 extensions.0.extend(new_extensions.0);
416
417 Error {
418 message,
419 source,
420 extensions: Some(extensions),
421 }
422 }
423}
424
425impl ErrorExtensions for Error {
426 fn extend(&self) -> Error {
427 self.clone()
428 }
429}
430
431impl<E: Display> ErrorExtensions for &E {
434 fn extend(&self) -> Error {
435 Error {
436 message: self.to_string(),
437 source: None,
438 extensions: None,
439 }
440 }
441}
442
443pub trait ResultExt<T, E>: Sized {
446 fn extend_err<C>(self, cb: C) -> Result<T>
448 where
449 C: FnOnce(&E, &mut ErrorExtensionValues);
450
451 fn extend(self) -> Result<T>;
453}
454
455impl<T, E> ResultExt<T, E> for std::result::Result<T, E>
458where
459 E: ErrorExtensions + Send + Sync + 'static,
460{
461 fn extend_err<C>(self, cb: C) -> Result<T>
462 where
463 C: FnOnce(&E, &mut ErrorExtensionValues),
464 {
465 match self {
466 Err(err) => Err(err.extend_with(|e, ee| cb(e, ee))),
467 Ok(value) => Ok(value),
468 }
469 }
470
471 fn extend(self) -> Result<T> {
472 match self {
473 Err(err) => Err(err.extend()),
474 Ok(value) => Ok(value),
475 }
476 }
477}