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
319#[cfg(not(feature = "custom-error-conversion"))]
320impl<T: Display + Send + Sync + 'static> From<T> for Error {
321 fn from(e: T) -> Self {
322 Self {
323 message: e.to_string(),
324 source: Some(Arc::new(e)),
325 extensions: None,
326 }
327 }
328}
329
330#[cfg(feature = "custom-error-conversion")]
331impl From<&'static str> for Error {
332 fn from(e: &'static str) -> Self {
333 Self {
334 message: e.to_string(),
335 source: None,
336 extensions: None,
337 }
338 }
339}
340
341#[cfg(feature = "custom-error-conversion")]
342impl From<String> for Error {
343 fn from(e: String) -> Self {
344 Self {
345 message: e,
346 source: None,
347 extensions: None,
348 }
349 }
350}
351
352pub type Result<T, E = Error> = std::result::Result<T, E>;
354
355#[derive(Debug, Error)]
357#[non_exhaustive]
358pub enum ParseRequestError {
359 #[error("{0}")]
361 Io(#[from] std::io::Error),
362
363 #[error("Invalid request: {0}")]
365 InvalidRequest(Box<dyn std::error::Error + Send + Sync>),
366
367 #[error("Invalid files map: {0}")]
369 InvalidFilesMap(Box<dyn std::error::Error + Send + Sync>),
370
371 #[error("Invalid multipart data")]
373 InvalidMultipart(multer::Error),
374
375 #[error("Missing \"operators\" part")]
377 MissingOperatorsPart,
378
379 #[error("Missing \"map\" part")]
381 MissingMapPart,
382
383 #[error("It's not an upload operation")]
385 NotUpload,
386
387 #[error("Missing files")]
389 MissingFiles,
390
391 #[error("Payload too large")]
393 PayloadTooLarge,
394
395 #[error("Batch requests are not supported")]
398 UnsupportedBatch,
399}
400
401impl From<multer::Error> for ParseRequestError {
402 fn from(err: multer::Error) -> Self {
403 match err {
404 multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => {
405 ParseRequestError::PayloadTooLarge
406 }
407 _ => ParseRequestError::InvalidMultipart(err),
408 }
409 }
410}
411
412impl From<mime::FromStrError> for ParseRequestError {
413 fn from(e: mime::FromStrError) -> Self {
414 Self::InvalidRequest(Box::new(e))
415 }
416}
417
418pub trait ErrorExtensions: Sized {
420 fn extend(&self) -> Error;
422
423 fn extend_with<C>(self, cb: C) -> Error
425 where
426 C: FnOnce(&Self, &mut ErrorExtensionValues),
427 {
428 let mut new_extensions = Default::default();
429 cb(&self, &mut new_extensions);
430
431 let Error {
432 message,
433 source,
434 extensions,
435 } = self.extend();
436
437 let mut extensions = extensions.unwrap_or_default();
438 extensions.0.extend(new_extensions.0);
439
440 Error {
441 message,
442 source,
443 extensions: Some(extensions),
444 }
445 }
446}
447
448impl ErrorExtensions for Error {
449 fn extend(&self) -> Error {
450 self.clone()
451 }
452}
453
454impl<E: Display> ErrorExtensions for &E {
457 fn extend(&self) -> Error {
458 Error {
459 message: self.to_string(),
460 source: None,
461 extensions: None,
462 }
463 }
464}
465
466pub trait ResultExt<T, E>: Sized {
469 fn extend_err<C>(self, cb: C) -> Result<T>
471 where
472 C: FnOnce(&E, &mut ErrorExtensionValues);
473
474 fn extend(self) -> Result<T>;
476}
477
478impl<T, E> ResultExt<T, E> for std::result::Result<T, E>
481where
482 E: ErrorExtensions + Send + Sync + 'static,
483{
484 fn extend_err<C>(self, cb: C) -> Result<T>
485 where
486 C: FnOnce(&E, &mut ErrorExtensionValues),
487 {
488 match self {
489 Err(err) => Err(err.extend_with(|e, ee| cb(e, ee))),
490 Ok(value) => Ok(value),
491 }
492 }
493
494 fn extend(self) -> Result<T> {
495 match self {
496 Err(err) => Err(err.extend()),
497 Ok(value) => Ok(value),
498 }
499 }
500}