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::{parser, InputType, Pos, Value};
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> {
125 self.source.as_ref().map(|err| err.downcast_ref()).flatten()
126 }
127
128 #[doc(hidden)]
129 #[must_use]
130 pub fn with_path(self, path: Vec<PathSegment>) -> Self {
131 Self { path, ..self }
132 }
133}
134
135impl Display for ServerError {
136 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
137 f.write_str(&self.message)
138 }
139}
140
141impl From<ServerError> for Vec<ServerError> {
142 fn from(single: ServerError) -> Self {
143 vec![single]
144 }
145}
146
147impl From<parser::Error> for ServerError {
148 fn from(e: parser::Error) -> Self {
149 Self {
150 message: e.to_string(),
151 source: None,
152 locations: e.positions().collect(),
153 path: Vec::new(),
154 extensions: None,
155 }
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
164#[serde(untagged)]
165pub enum PathSegment {
166 Field(String),
168 Index(usize),
170}
171
172pub type ServerResult<T> = std::result::Result<T, ServerError>;
174
175#[derive(Debug)]
180pub struct InputValueError<T> {
181 message: String,
182 extensions: Option<ErrorExtensionValues>,
183 phantom: PhantomData<T>,
184}
185
186impl<T: InputType> InputValueError<T> {
187 fn new(message: String, extensions: Option<ErrorExtensionValues>) -> Self {
188 Self {
189 message,
190 extensions,
191 phantom: PhantomData,
192 }
193 }
194
195 #[must_use]
197 pub fn expected_type(actual: Value) -> Self {
198 Self::new(
199 format!(
200 r#"Expected input type "{}", found {}."#,
201 T::type_name(),
202 actual
203 ),
204 None,
205 )
206 }
207
208 #[must_use]
213 pub fn custom(msg: impl Display) -> Self {
214 Self::new(
215 format!(r#"Failed to parse "{}": {}"#, T::type_name(), msg),
216 None,
217 )
218 }
219
220 pub fn propagate<U: InputType>(self) -> InputValueError<U> {
222 if T::type_name() != U::type_name() {
223 InputValueError::new(
224 format!(
225 r#"{} (occurred while parsing "{}")"#,
226 self.message,
227 U::type_name()
228 ),
229 self.extensions,
230 )
231 } else {
232 InputValueError::new(self.message, self.extensions)
233 }
234 }
235
236 pub fn with_extension(mut self, name: impl AsRef<str>, value: impl Into<Value>) -> Self {
238 self.extensions
239 .get_or_insert_with(ErrorExtensionValues::default)
240 .set(name, value);
241 self
242 }
243
244 pub fn into_server_error(self, pos: Pos) -> ServerError {
246 let mut err = ServerError::new(self.message, Some(pos));
247 err.extensions = self.extensions;
248 err
249 }
250}
251
252impl<T: InputType, E: Display> From<E> for InputValueError<T> {
253 fn from(error: E) -> Self {
254 Self::custom(error)
255 }
256}
257
258pub type InputValueResult<T> = Result<T, InputValueError<T>>;
260
261#[derive(Clone, Serialize)]
263pub struct Error {
264 pub message: String,
266 #[serde(skip)]
268 pub source: Option<Arc<dyn Any + Send + Sync>>,
269 #[serde(skip_serializing_if = "error_extensions_is_empty")]
271 pub extensions: Option<ErrorExtensionValues>,
272}
273
274impl Debug for Error {
275 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
276 f.debug_struct("Error")
277 .field("message", &self.message)
278 .field("extensions", &self.extensions)
279 .finish()
280 }
281}
282
283impl PartialEq for Error {
284 fn eq(&self, other: &Self) -> bool {
285 self.message.eq(&other.message) && self.extensions.eq(&other.extensions)
286 }
287}
288
289impl Error {
290 pub fn new(message: impl Into<String>) -> Self {
292 Self {
293 message: message.into(),
294 source: None,
295 extensions: None,
296 }
297 }
298
299 pub fn new_with_source(source: impl Display + Send + Sync + 'static) -> Self {
302 Self {
303 message: source.to_string(),
304 source: Some(Arc::new(source)),
305 extensions: None,
306 }
307 }
308
309 #[must_use]
311 pub fn into_server_error(self, pos: Pos) -> ServerError {
312 ServerError {
313 message: self.message,
314 source: self.source,
315 locations: vec![pos],
316 path: Vec::new(),
317 extensions: self.extensions,
318 }
319 }
320}
321
322#[cfg(not(feature = "custom-error-conversion"))]
323impl<T: Display + Send + Sync + 'static> From<T> for Error {
324 fn from(e: T) -> Self {
325 Self {
326 message: e.to_string(),
327 source: Some(Arc::new(e)),
328 extensions: None,
329 }
330 }
331}
332
333#[cfg(feature = "custom-error-conversion")]
334impl From<&'static str> for Error {
335 fn from(e: &'static str) -> Self {
336 Self {
337 message: e.to_string(),
338 source: None,
339 extensions: None,
340 }
341 }
342}
343
344#[cfg(feature = "custom-error-conversion")]
345impl From<String> for Error {
346 fn from(e: String) -> Self {
347 Self {
348 message: e,
349 source: None,
350 extensions: None,
351 }
352 }
353}
354
355pub type Result<T, E = Error> = std::result::Result<T, E>;
357
358#[derive(Debug, Error)]
360#[non_exhaustive]
361pub enum ParseRequestError {
362 #[error("{0}")]
364 Io(#[from] std::io::Error),
365
366 #[error("Invalid request: {0}")]
368 InvalidRequest(Box<dyn std::error::Error + Send + Sync>),
369
370 #[error("Invalid files map: {0}")]
372 InvalidFilesMap(Box<dyn std::error::Error + Send + Sync>),
373
374 #[error("Invalid multipart data")]
376 InvalidMultipart(multer::Error),
377
378 #[error("Missing \"operators\" part")]
380 MissingOperatorsPart,
381
382 #[error("Missing \"map\" part")]
384 MissingMapPart,
385
386 #[error("It's not an upload operation")]
388 NotUpload,
389
390 #[error("Missing files")]
392 MissingFiles,
393
394 #[error("Payload too large")]
396 PayloadTooLarge,
397
398 #[error("Batch requests are not supported")]
401 UnsupportedBatch,
402}
403
404impl From<multer::Error> for ParseRequestError {
405 fn from(err: multer::Error) -> Self {
406 match err {
407 multer::Error::FieldSizeExceeded { .. } | multer::Error::StreamSizeExceeded { .. } => {
408 ParseRequestError::PayloadTooLarge
409 }
410 _ => ParseRequestError::InvalidMultipart(err),
411 }
412 }
413}
414
415impl From<mime::FromStrError> for ParseRequestError {
416 fn from(e: mime::FromStrError) -> Self {
417 Self::InvalidRequest(Box::new(e))
418 }
419}
420
421pub trait ErrorExtensions: Sized {
423 fn extend(&self) -> Error;
425
426 fn extend_with<C>(self, cb: C) -> Error
428 where
429 C: FnOnce(&Self, &mut ErrorExtensionValues),
430 {
431 let mut new_extensions = Default::default();
432 cb(&self, &mut new_extensions);
433
434 let Error {
435 message,
436 source,
437 extensions,
438 } = self.extend();
439
440 let mut extensions = extensions.unwrap_or_default();
441 extensions.0.extend(new_extensions.0);
442
443 Error {
444 message,
445 source,
446 extensions: Some(extensions),
447 }
448 }
449}
450
451impl ErrorExtensions for Error {
452 fn extend(&self) -> Error {
453 self.clone()
454 }
455}
456
457impl<E: Display> ErrorExtensions for &E {
460 fn extend(&self) -> Error {
461 Error {
462 message: self.to_string(),
463 source: None,
464 extensions: None,
465 }
466 }
467}
468
469pub trait ResultExt<T, E>: Sized {
472 fn extend_err<C>(self, cb: C) -> Result<T>
474 where
475 C: FnOnce(&E, &mut ErrorExtensionValues);
476
477 fn extend(self) -> Result<T>;
479}
480
481impl<T, E> ResultExt<T, E> for std::result::Result<T, E>
484where
485 E: ErrorExtensions + Send + Sync + 'static,
486{
487 fn extend_err<C>(self, cb: C) -> Result<T>
488 where
489 C: FnOnce(&E, &mut ErrorExtensionValues),
490 {
491 match self {
492 Err(err) => Err(err.extend_with(|e, ee| cb(e, ee))),
493 Ok(value) => Ok(value),
494 }
495 }
496
497 fn extend(self) -> Result<T> {
498 match self {
499 Err(err) => Err(err.extend()),
500 Ok(value) => Ok(value),
501 }
502 }
503}