rocket/form/error.rs
1//! Form error types.
2
3use std::{fmt, io};
4use std::num::{ParseIntError, ParseFloatError};
5use std::str::{Utf8Error, ParseBoolError};
6use std::char::ParseCharError;
7use std::net::AddrParseError;
8use std::borrow::Cow;
9
10use serde::{Serialize, ser::{Serializer, SerializeStruct}};
11
12use crate::http::Status;
13use crate::form::name::{NameBuf, Name};
14use crate::data::ByteUnit;
15
16/// A collection of [`Error`]s.
17///
18/// `Errors` is a thin wrapper around a `Vec<Error>` with convenient methods for
19/// modifying the internal `Error`s. It `Deref`s and `DerefMut`s to
20/// `Vec<Error>` for transparent access to the underlying vector.
21///
22/// # Matching Errors to Fields
23///
24/// To find the errors that correspond to a given field, use
25/// [`Error::is_for()`]. For example, to get all of the errors that correspond
26/// to the field `foo.bar`, you might write the following:
27///
28/// ```rust
29/// use rocket::form::Errors;
30///
31/// let errors = Errors::new();
32/// let errors_for_foo = errors.iter().filter(|e| e.is_for("foo.bar"));
33/// ```
34///
35/// ## Constructing
36///
37/// An `Errors` can be constructed from anything that an `Error` can be
38/// constructed from. This includes [`Error`], [`ErrorKind`], and all of the
39/// types an `ErrorKind` can be constructed from. See
40/// [`ErrorKind`](ErrorKind#constructing) for the full list.
41///
42/// ```rust
43/// use rocket::form;
44///
45/// fn at_most_10() -> form::Result<'static, usize> {
46/// // Using `From<PartIntError> => ErrorKind::Int => Errors`.
47/// let i: usize = "foo".parse()?;
48///
49/// if i > 10 {
50/// // `(Option<isize>, Option<isize>) => ErrorKind::OutOfRange => Errors`
51/// return Err((None, Some(10isize)).into());
52/// }
53///
54/// Ok(i)
55/// }
56/// ```
57#[derive(Default, Debug, PartialEq, Serialize)]
58#[serde(transparent)]
59pub struct Errors<'v>(Vec<Error<'v>>);
60
61/// A form error, potentially tied to a specific form field.
62///
63/// An `Error` is returned by [`FromForm`], [`FromFormField`], and [`validate`]
64/// procedures, typically as a collection of [`Errors`]. It potentially
65/// identifies a specific field that triggered the error via [`Error::name`] and
66/// the field's value via [`Error::value`].
67///
68/// An `Error` can occur because of a field's value that failed to parse or
69/// because other parts of a field or form were malformed; the [`Error::entity`]
70/// identifies the part of the form that resulted in the error.
71///
72/// [`FromForm`]: crate::form::FromForm
73/// [`FromFormField`]: crate::form::FromFormField
74/// [`validate`]: crate::form::validate
75///
76/// # Constructing
77///
78/// An `Error` can be constructed via [`Error::validation()`],
79/// [`Error::custom()`], or anything that an [`ErrorKind`] can be constructed
80/// from. See [`ErrorKind`](ErrorKind#constructing).
81///
82/// ```rust
83/// use rocket::form::Error;
84///
85/// fn at_most_10_not_even() -> Result<usize, Error<'static>> {
86/// // Using `From<PartIntError> => ErrorKind::Int`.
87/// let i: usize = "foo".parse()?;
88///
89/// if i > 10 {
90/// // `From<(Option<isize>, Option<isize>)> => ErrorKind::OutOfRange`
91/// return Err((None, Some(10isize)).into());
92/// } else if i % 2 == 0 {
93/// return Err(Error::validation("integer cannot be even"));
94/// }
95///
96/// Ok(i)
97/// }
98/// ```
99///
100/// # Setting Field Metadata
101///
102/// When implementing [`FromFormField`], nothing has to be done for a field's
103/// metadata to be set: the blanket [`FromForm`] implementation sets it
104/// automatically.
105///
106/// When constructed from an `ErrorKind`, the entity is set to
107/// [`Entity::default_for()`] by default. Occasionally, the error's `entity` may
108/// need to be set manually. Return what would be useful to the end-consumer.
109///
110/// # Matching Errors to Fields
111///
112/// To determine whether an error corresponds to a given field, use
113/// [`Error::is_for()`]. For example, to get all of the errors that correspond
114/// to the field `foo.bar`, you might write the following:
115///
116/// ```rust
117/// use rocket::form::Errors;
118///
119/// let errors = Errors::new();
120/// let errors_for_foo = errors.iter().filter(|e| e.is_for("foo.bar"));
121/// ```
122///
123/// # Serialization
124///
125/// When a value of this type is serialized, a `struct` or map with the
126/// following fields is emitted:
127///
128/// | field | type | description |
129/// |----------|----------------|--------------------------------------------------|
130/// | `name` | `Option<&str>` | the erroring field's name, if known |
131/// | `value` | `Option<&str>` | the erroring field's value, if known |
132/// | `entity` | `&str` | string representation of the erroring [`Entity`] |
133/// | `msg` | `&str` | concise message of the error |
134#[derive(Debug, PartialEq)]
135pub struct Error<'v> {
136 /// The name of the field, if it is known.
137 pub name: Option<NameBuf<'v>>,
138 /// The field's value, if it is known.
139 pub value: Option<Cow<'v, str>>,
140 /// The kind of error that occurred.
141 pub kind: ErrorKind<'v>,
142 /// The entity that caused the error.
143 pub entity: Entity,
144}
145
146/// The kind of form error that occurred.
147///
148/// ## Constructing
149///
150/// An `ErrorKind` can be constructed directly or via a `From` of the following
151/// types:
152///
153/// * `(Option<u64>, Option<u64>)` => [`ErrorKind::InvalidLength`]
154/// * `(Option<ByteUnit>, Option<ByteUnit>)` => [`ErrorKind::InvalidLength`]
155/// * `(Option<isize>, Option<isize>)` => [`ErrorKind::OutOfRange`]
156/// * `&[Cow<'_, str>]` or `Vec<Cow<'_, str>>` => [`ErrorKind::InvalidChoice`]
157/// * [`Utf8Error`] => [`ErrorKind::Utf8`]
158/// * [`ParseIntError`] => [`ErrorKind::Int`]
159/// * [`ParseFloatError`] => [`ErrorKind::Float`]
160/// * [`ParseBoolError`] => [`ErrorKind::Bool`]
161/// * [`AddrParseError`] => [`ErrorKind::Addr`]
162/// * [`io::Error`] => [`ErrorKind::Io`]
163/// * `Box<dyn std::error::Error + Send` => [`ErrorKind::Custom`]
164/// * `(Status, Box<dyn std::error::Error + Send)` => [`ErrorKind::Custom`]
165#[derive(Debug)]
166#[non_exhaustive]
167pub enum ErrorKind<'v> {
168 /// The value's length, in bytes, was outside the range `[min, max]`.
169 InvalidLength {
170 /// The minimum length required, inclusive.
171 min: Option<u64>,
172 /// The maximum length required, inclusive.
173 max: Option<u64>,
174 },
175 /// The value wasn't one of the valid `choices`.
176 InvalidChoice {
177 /// The choices that were expected.
178 choices: Cow<'v, [Cow<'v, str>]>,
179 },
180 /// The integer value was outside the range `[start, end]`.
181 OutOfRange {
182 /// The start of the acceptable range, inclusive.
183 start: Option<isize>,
184 /// The end of the acceptable range, inclusive.
185 end: Option<isize>,
186 },
187 /// A custom validation routine failed with message `.0`.
188 Validation(Cow<'v, str>),
189 /// One entity was expected but more than one was received.
190 Duplicate,
191 /// An entity was expected but was not received.
192 Missing,
193 /// An unexpected entity was received.
194 Unexpected,
195 /// An unknown entity was received.
196 Unknown,
197 /// A custom error occurred. Status defaults to
198 /// [`Status::UnprocessableEntity`] if one is not directly specified.
199 Custom(Status, Box<dyn std::error::Error + Send>),
200 /// An error while parsing a multipart form occurred.
201 Multipart(multer::Error),
202 /// A string was invalid UTF-8.
203 Utf8(Utf8Error),
204 /// A value failed to parse as a char.
205 Char(ParseCharError),
206 /// A value failed to parse as an integer.
207 Int(ParseIntError),
208 /// A value failed to parse as a boolean.
209 Bool(ParseBoolError),
210 /// A value failed to parse as a float.
211 Float(ParseFloatError),
212 /// A value failed to parse as an IP or socket address.
213 Addr(AddrParseError),
214 /// An I/O error occurred.
215 Io(io::Error),
216}
217
218/// The erroneous form entity or form component.
219#[derive(Debug, Copy, Clone, PartialEq, Eq)]
220pub enum Entity {
221 /// The form itself.
222 Form,
223 /// A field.
224 Field,
225 /// A [`ValueField`](crate::form::ValueField).
226 ValueField,
227 /// A [`DataField`](crate::form::DataField).
228 DataField,
229 /// A field name.
230 Name,
231 /// A field value.
232 Value,
233 /// A field name key.
234 Key,
235 /// A field name key index at index `.0`.
236 Index(usize),
237}
238
239impl<'v> Errors<'v> {
240 /// Create an empty collection of errors.
241 ///
242 /// # Example
243 ///
244 /// ```rust
245 /// use rocket::form::Errors;
246 ///
247 /// let errors = Errors::new();
248 /// assert!(errors.is_empty());
249 /// ```
250 pub fn new() -> Self {
251 Errors(vec![])
252 }
253
254 /// Consumes `self` and returns a new `Errors` with each field name set to
255 /// `name` if it was not already set.
256 ///
257 /// # Example
258 ///
259 /// ```rust
260 /// use rocket::form::error::{Errors, ErrorKind};
261 ///
262 /// let mut errors = Errors::from(ErrorKind::Missing);
263 /// assert!(errors[0].name.is_none());
264 ///
265 /// let mut errors = errors.with_name("foo");
266 /// assert_eq!(errors[0].name.as_ref().unwrap(), "foo");
267 ///
268 /// errors.push(ErrorKind::Duplicate.into());
269 /// let errors = errors.with_name("bar");
270 /// assert_eq!(errors[0].name.as_ref().unwrap(), "foo");
271 /// assert_eq!(errors[1].name.as_ref().unwrap(), "bar");
272 /// ```
273 pub fn with_name<N: Into<NameBuf<'v>>>(mut self, name: N) -> Self {
274 self.set_name(name);
275 self
276 }
277
278 /// Set the field name of each error in `self` to `name` if it is not
279 /// already set.
280 ///
281 /// # Example
282 ///
283 /// ```rust
284 /// use rocket::form::error::{Errors, ErrorKind};
285 ///
286 /// let mut errors = Errors::from(ErrorKind::Missing);
287 /// assert!(errors[0].name.is_none());
288 ///
289 /// errors.set_name("foo");
290 /// assert_eq!(errors[0].name.as_ref().unwrap(), "foo");
291 ///
292 /// errors.push(ErrorKind::Duplicate.into());
293 /// let errors = errors.with_name("bar");
294 /// assert_eq!(errors[0].name.as_ref().unwrap(), "foo");
295 /// assert_eq!(errors[1].name.as_ref().unwrap(), "bar");
296 /// ```
297 pub fn set_name<N: Into<NameBuf<'v>>>(&mut self, name: N) {
298 let name = name.into();
299 for error in self.iter_mut() {
300 if error.name.is_none() {
301 error.set_name(name.clone());
302 }
303 }
304 }
305
306 /// Consumes `self` and returns a new `Errors` with each field value set to
307 /// `value` if it was not already set.
308 ///
309 /// # Example
310 ///
311 /// ```rust
312 /// use rocket::form::error::{Errors, ErrorKind};
313 ///
314 /// let mut errors = Errors::from(ErrorKind::Missing);
315 /// assert!(errors[0].value.is_none());
316 ///
317 /// let mut errors = errors.with_value("foo");
318 /// assert_eq!(errors[0].value.as_ref().unwrap(), "foo");
319 ///
320 /// errors.push(ErrorKind::Duplicate.into());
321 /// let errors = errors.with_value("bar");
322 /// assert_eq!(errors[0].value.as_ref().unwrap(), "foo");
323 /// assert_eq!(errors[1].value.as_ref().unwrap(), "bar");
324 /// ```
325 pub fn with_value(mut self, value: &'v str) -> Self {
326 self.set_value(value);
327 self
328 }
329
330 /// Set the field value of each error in `self` to `value` if it is not
331 /// already set.
332 ///
333 /// # Example
334 ///
335 /// ```rust
336 /// use rocket::form::error::{Errors, ErrorKind};
337 ///
338 /// let mut errors = Errors::from(ErrorKind::Missing);
339 /// assert!(errors[0].value.is_none());
340 ///
341 /// errors.set_value("foo");
342 /// assert_eq!(errors[0].value.as_ref().unwrap(), "foo");
343 ///
344 /// errors.push(ErrorKind::Duplicate.into());
345 /// let errors = errors.with_value("bar");
346 /// assert_eq!(errors[0].value.as_ref().unwrap(), "foo");
347 /// assert_eq!(errors[1].value.as_ref().unwrap(), "bar");
348 /// ```
349 pub fn set_value(&mut self, value: &'v str) {
350 self.iter_mut().for_each(|e| e.set_value(value));
351 }
352
353 /// Returns the highest [`Error::status()`] of all of the errors in `self`
354 /// or [`Status::InternalServerError`] if `self` is empty. This is the
355 /// status that is set by the [`Form`](crate::form::Form) data guard on
356 /// error.
357 ///
358 /// See [`Error::status()`] for the corresponding status code of each
359 /// [`Error`] variant.
360 ///
361 /// # Example
362 ///
363 /// ```rust
364 /// use rocket::form::error::{Error, Errors, ErrorKind};
365 /// use rocket::http::Status;
366 ///
367 /// let mut errors = Errors::new();
368 /// assert_eq!(errors.status(), Status::InternalServerError);
369 ///
370 /// errors.push(Error::from((None, Some(10u64))));
371 /// assert_eq!(errors.status(), Status::PayloadTooLarge);
372 ///
373 /// errors.push(Error::from(ErrorKind::Missing));
374 /// assert_eq!(errors.status(), Status::UnprocessableEntity);
375 /// ```
376 pub fn status(&self) -> Status {
377 let max = self.iter().map(|e| e.status()).max();
378 max.unwrap_or(Status::InternalServerError)
379 }
380}
381
382impl crate::http::ext::IntoOwned for Errors<'_> {
383 type Owned = Errors<'static>;
384
385 fn into_owned(self) -> Self::Owned {
386 Errors(self.0.into_owned())
387 }
388}
389
390impl fmt::Display for Errors<'_> {
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 write!(f, "{} error(s):", self.len())?;
393 for error in self.iter() {
394 write!(f, "\n{}", error)?;
395 }
396
397 Ok(())
398 }
399}
400
401impl<'v> std::ops::Deref for Errors<'v> {
402 type Target = Vec<Error<'v>>;
403
404 fn deref(&self) -> &Self::Target {
405 &self.0
406 }
407}
408
409impl<'v> std::ops::DerefMut for Errors<'v> {
410 fn deref_mut(&mut self) -> &mut Self::Target {
411 &mut self.0
412 }
413}
414
415impl<'v, T: Into<Error<'v>>> From<T> for Errors<'v> {
416 #[inline(always)]
417 fn from(e: T) -> Self {
418 Errors(vec![e.into()])
419 }
420}
421
422impl<'v> From<Vec<Error<'v>>> for Errors<'v> {
423 #[inline(always)]
424 fn from(v: Vec<Error<'v>>) -> Self {
425 Errors(v)
426 }
427}
428
429impl<'v> IntoIterator for Errors<'v> {
430 type Item = Error<'v>;
431
432 type IntoIter = <Vec<Error<'v>> as IntoIterator>::IntoIter;
433
434 fn into_iter(self) -> Self::IntoIter {
435 self.0.into_iter()
436 }
437}
438
439impl<'v> Error<'v> {
440 /// Creates a new `Error` with `ErrorKind::Custom`.
441 ///
442 /// For validation errors, use [`Error::validation()`].
443 ///
444 /// # Example
445 ///
446 /// ```rust
447 /// use rocket::form::Error;
448 ///
449 /// fn from_fmt(error: std::fmt::Error) -> Error<'static> {
450 /// Error::custom(error)
451 /// }
452 /// ```
453 pub fn custom<E>(error: E) -> Self
454 where E: std::error::Error + Send + 'static
455 {
456 (Box::new(error) as Box<dyn std::error::Error + Send>).into()
457 }
458
459 /// Creates a new `Error` with `ErrorKind::Validation` and message `msg`.
460 ///
461 /// # Example
462 ///
463 /// ```rust
464 /// use rocket::form::error::{Error, ErrorKind, Entity};
465 ///
466 /// let error = Error::validation("invalid foo: need bar");
467 /// assert!(matches!(error.kind, ErrorKind::Validation(_)));
468 /// assert_eq!(error.entity, Entity::Value);
469 /// ```
470 pub fn validation<S: Into<Cow<'v, str>>>(msg: S) -> Self {
471 ErrorKind::Validation(msg.into()).into()
472 }
473
474 /// Consumes `self` and returns a new `Error` with the entity set to
475 /// `entity`.
476 ///
477 /// # Example
478 ///
479 /// ```rust
480 /// use rocket::form::error::{Error, ErrorKind, Entity};
481 ///
482 /// let error = Error::from(ErrorKind::Missing);
483 /// assert_eq!(error.entity, Entity::Field);
484 ///
485 /// let error = error.with_entity(Entity::Key);
486 /// assert_eq!(error.entity, Entity::Key);
487 /// ```
488 pub fn with_entity(mut self, entity: Entity) -> Self {
489 self.set_entity(entity);
490 self
491 }
492
493 /// Sets the error's entity to `entity.`
494 ///
495 /// # Example
496 ///
497 /// ```rust
498 /// use rocket::form::error::{Error, ErrorKind, Entity};
499 ///
500 /// let mut error = Error::from(ErrorKind::Missing);
501 /// assert_eq!(error.entity, Entity::Field);
502 ///
503 /// error.set_entity(Entity::Key);
504 /// assert_eq!(error.entity, Entity::Key);
505 /// ```
506 pub fn set_entity(&mut self, entity: Entity) {
507 self.entity = entity;
508 }
509
510 /// Consumes `self` and returns a new `Error` with the field name set to
511 /// `name` if it was not already set.
512 ///
513 /// # Example
514 ///
515 /// ```rust
516 /// use rocket::form::error::{Error, ErrorKind};
517 ///
518 /// let error = Error::from(ErrorKind::Missing);
519 /// assert!(error.name.is_none());
520 ///
521 /// let error = error.with_name("foo");
522 /// assert_eq!(error.name.as_ref().unwrap(), "foo");
523 ///
524 /// let error = error.with_name("bar");
525 /// assert_eq!(error.name.as_ref().unwrap(), "foo");
526 /// ```
527 pub fn with_name<N: Into<NameBuf<'v>>>(mut self, name: N) -> Self {
528 self.set_name(name);
529 self
530 }
531
532 /// Sets the field name of `self` to `name` if it is not already set.
533 ///
534 /// # Example
535 ///
536 /// ```rust
537 /// use rocket::form::error::{Error, ErrorKind};
538 ///
539 /// let mut error = Error::from(ErrorKind::Missing);
540 /// assert!(error.name.is_none());
541 ///
542 /// error.set_name("foo");
543 /// assert_eq!(error.name.as_ref().unwrap(), "foo");
544 ///
545 /// let error = error.with_name("bar");
546 /// assert_eq!(error.name.as_ref().unwrap(), "foo");
547 /// ```
548 pub fn set_name<N: Into<NameBuf<'v>>>(&mut self, name: N) {
549 if self.name.is_none() {
550 self.name = Some(name.into());
551 }
552 }
553
554 /// Consumes `self` and returns a new `Error` with the value set to `value`
555 /// if it was not already set.
556 ///
557 /// # Example
558 ///
559 /// ```rust
560 /// use rocket::form::error::{Error, ErrorKind};
561 ///
562 /// let error = Error::from(ErrorKind::Missing);
563 /// assert!(error.value.is_none());
564 ///
565 /// let error = error.with_value("foo");
566 /// assert_eq!(error.value.as_ref().unwrap(), "foo");
567 ///
568 /// let error = error.with_value("bar");
569 /// assert_eq!(error.value.as_ref().unwrap(), "foo");
570 /// ```
571 pub fn with_value(mut self, value: &'v str) -> Self {
572 self.set_value(value);
573 self
574 }
575
576 /// Set the field value of `self` to `value` if it is not already set.
577 ///
578 /// # Example
579 ///
580 /// ```rust
581 /// use rocket::form::error::{Error, ErrorKind};
582 ///
583 /// let mut error = Error::from(ErrorKind::Missing);
584 /// assert!(error.value.is_none());
585 ///
586 /// error.set_value("foo");
587 /// assert_eq!(error.value.as_ref().unwrap(), "foo");
588 ///
589 /// error.set_value("bar");
590 /// assert_eq!(error.value.as_ref().unwrap(), "foo");
591 /// ```
592 pub fn set_value(&mut self, value: &'v str) {
593 if self.value.is_none() {
594 self.value = Some(value.into());
595 }
596 }
597
598 /// Returns `true` if this error applies to a field named `name`. **This is
599 /// _different_ than simply comparing `name`.**
600 ///
601 /// Unlike [`Error::is_for_exactly()`], this method returns `true` if the
602 /// error's field name is a **prefix of `name`**. This is typically what is
603 /// desired as errors apply to a field and its children: `a.b` applies to
604 /// the nested fields `a.b.c`, `a.b.d` and so on.
605 ///
606 /// Returns `false` if `self` has no field name.
607 ///
608 /// # Example
609 ///
610 /// ```rust
611 /// use rocket::form::Error;
612 ///
613 /// // returns `false` without a field name
614 /// let error = Error::validation("bad `foo`");
615 /// assert!(!error.is_for_exactly("a.b"));
616 ///
617 /// // `a.b` is a prefix all of these field names
618 /// let error = error.with_name("a.b");
619 /// assert!(error.is_for("a.b"));
620 /// assert!(error.is_for("a[b]"));
621 /// assert!(error.is_for("a.b.c"));
622 /// assert!(error.is_for("a.b[c]"));
623 /// assert!(error.is_for("a.b.c[d]"));
624 /// assert!(error.is_for("a.b.c.d.foo"));
625 ///
626 /// // ...but not of these.
627 /// assert!(!error.is_for("a.c"));
628 /// assert!(!error.is_for("a"));
629 /// ```
630 pub fn is_for<N: AsRef<Name>>(&self, name: N) -> bool {
631 self.name.as_ref().map(|e_name| {
632 if e_name.is_empty() != name.as_ref().is_empty() {
633 return false;
634 }
635
636 let mut e_keys = e_name.keys();
637 let mut n_keys = name.as_ref().keys();
638 loop {
639 match (e_keys.next(), n_keys.next()) {
640 (Some(e), Some(n)) if e == n => continue,
641 (Some(_), Some(_)) => return false,
642 (Some(_), None) => return false,
643 (None, _) => break,
644 }
645 }
646
647 true
648 })
649 .unwrap_or(false)
650 }
651
652 /// Returns `true` if this error applies to exactly the field named `name`.
653 /// Returns `false` if `self` has no field name.
654 ///
655 /// Unlike [`Error::is_for()`], this method returns `true` only when the
656 /// error's field name is exactly `name`. This is _not_ typically what is
657 /// desired.
658 ///
659 /// # Example
660 ///
661 /// ```rust
662 /// use rocket::form::Error;
663 ///
664 /// // returns `false` without a field name
665 /// let error = Error::validation("bad `foo`");
666 /// assert!(!error.is_for_exactly("a.b"));
667 ///
668 /// let error = error.with_name("a.b");
669 /// assert!(error.is_for_exactly("a.b"));
670 /// assert!(error.is_for_exactly("a[b]"));
671 ///
672 /// // does not return `true` when the name is a prefix
673 /// assert!(!error.is_for_exactly("a.b.c"));
674 /// assert!(!error.is_for_exactly("a.b[c]"));
675 /// assert!(!error.is_for_exactly("a.b.c[d]"));
676 /// assert!(!error.is_for_exactly("a.b.c.d.foo"));
677 ///
678 /// // does not return `true` when the name is different
679 /// assert!(!error.is_for("a.c"));
680 /// assert!(!error.is_for("a"));
681 /// ```
682 pub fn is_for_exactly<N: AsRef<Name>>(&self, name: N) -> bool {
683 self.name.as_ref()
684 .map(|n| name.as_ref() == n)
685 .unwrap_or(false)
686 }
687
688 /// Returns the most reasonable [`Status`] associated with this error.
689 ///
690 /// For an [`ErrorKind::Custom`], this is the variant's `Status`, which
691 /// defaults to [`Status::UnprocessableEntity`]. For all others, it is:
692 ///
693 /// * **`PayloadTooLarge`** if the [error kind](ErrorKind) is:
694 /// - `InvalidLength` with min of `None`
695 /// - `Multipart(FieldSizeExceeded)` or `Multipart(StreamSizeExceeded)`
696 /// * **`InternalServerError`** if the [error kind](ErrorKind) is:
697 /// - `Unknown`
698 /// * **`BadRequest`** if the [error kind](ErrorKind) is:
699 /// - `Io` with an `entity` of `Form`
700 /// * **`UnprocessableEntity`** for all other variants
701 ///
702 /// # Example
703 ///
704 /// ```rust
705 /// use rocket::form::error::{Error, ErrorKind, Entity};
706 /// use rocket::http::Status;
707 ///
708 /// let error = Error::validation("bad `foo`");
709 /// assert_eq!(error.status(), Status::UnprocessableEntity);
710 ///
711 /// let error = Error::from((None, Some(10u64)));
712 /// assert_eq!(error.status(), Status::PayloadTooLarge);
713 ///
714 /// let error = Error::from(ErrorKind::Unknown);
715 /// assert_eq!(error.status(), Status::InternalServerError);
716 ///
717 /// // default entity for `io::Error` is `Form`.
718 /// let error = Error::from(std::io::Error::last_os_error());
719 /// assert_eq!(error.status(), Status::BadRequest);
720 ///
721 /// let error = error.with_entity(Entity::Value);
722 /// assert_eq!(error.status(), Status::UnprocessableEntity);
723 /// ```
724 pub fn status(&self) -> Status {
725 use ErrorKind::*;
726 use multer::Error::*;
727
728 match self.kind {
729 | InvalidLength { min: None, .. }
730 | Multipart(FieldSizeExceeded { .. })
731 | Multipart(StreamSizeExceeded { .. }) => Status::PayloadTooLarge,
732 Unknown => Status::InternalServerError,
733 Io(_) | _ if self.entity == Entity::Form => Status::BadRequest,
734 Custom(status, _) => status,
735 _ => Status::UnprocessableEntity
736 }
737 }
738}
739
740impl<'v> Serialize for Error<'v> {
741 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
742 let mut err = ser.serialize_struct("Error", 3)?;
743 err.serialize_field("name", &self.name)?;
744 err.serialize_field("value", &self.value)?;
745 err.serialize_field("entity", &self.entity.to_string())?;
746 err.serialize_field("msg", &self.to_string())?;
747 err.end()
748 }
749}
750
751impl crate::http::ext::IntoOwned for Error<'_> {
752 type Owned = Error<'static>;
753
754 fn into_owned(self) -> Self::Owned {
755 Error {
756 name: self.name.into_owned(),
757 value: self.value.into_owned(),
758 kind: self.kind.into_owned(),
759 entity: self.entity,
760 }
761 }
762}
763
764impl<'v> std::ops::Deref for Error<'v> {
765 type Target = ErrorKind<'v>;
766
767 fn deref(&self) -> &Self::Target {
768 &self.kind
769 }
770}
771
772impl fmt::Display for Error<'_> {
773 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
774 self.kind.fmt(f)
775 }
776}
777
778impl<'v, T: Into<ErrorKind<'v>>> From<T> for Error<'v> {
779 #[inline(always)]
780 fn from(k: T) -> Self {
781 let kind = k.into();
782 let entity = Entity::default_for(&kind);
783 Error { name: None, value: None, kind, entity }
784 }
785}
786
787impl<'a> From<multer::Error> for Error<'a> {
788 fn from(error: multer::Error) -> Self {
789 use multer::Error::*;
790 use self::ErrorKind::*;
791
792 let incomplete = Error::from(InvalidLength { min: None, max: None });
793 match error {
794 UnknownField { field_name: Some(name) } => Error::from(Unexpected).with_name(name),
795 UnknownField { field_name: None } => Error::from(Unexpected),
796 FieldSizeExceeded { limit, field_name } => {
797 let e = Error::from((None, Some(limit)));
798 match field_name {
799 Some(name) => e.with_name(name),
800 None => e
801 }
802 },
803 StreamSizeExceeded { limit } => {
804 Error::from((None, Some(limit))).with_entity(Entity::Form)
805 }
806 IncompleteFieldData { field_name: Some(name) } => incomplete.with_name(name),
807 IncompleteFieldData { field_name: None } => incomplete,
808 IncompleteStream | IncompleteHeaders => incomplete.with_entity(Entity::Form),
809 e => Error::from(ErrorKind::Multipart(e))
810 }
811 }
812}
813
814impl fmt::Display for ErrorKind<'_> {
815 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
816 match self {
817 ErrorKind::InvalidLength { min, max } => {
818 match (min, max) {
819 (None, None) => write!(f, "invalid length: incomplete")?,
820 (None, Some(k)) if *k < 1024 => write!(f, "length cannot exceed {}", k)?,
821 (None, Some(k)) => write!(f, "size must not exceed {}", ByteUnit::from(*k))?,
822 (Some(1), None) => write!(f, "cannot be empty")?,
823 (Some(k), None) if *k < 1024 => write!(f, "expected at least {}", k)?,
824 (Some(k), None) => write!(f, "size must be at least {}", ByteUnit::from(*k))?,
825 (Some(i), Some(j)) if *i < 1024 && *j < 1024 => {
826 write!(f, "length must be between {} and {}", i, j)?;
827 }
828 (Some(i), Some(j)) => {
829 let (i, j) = (ByteUnit::from(*i), ByteUnit::from(*j));
830 write!(f, "size must be between {} and {}", i, j)?;
831 }
832 }
833 }
834 ErrorKind::InvalidChoice { choices } => {
835 match *choices.as_ref() {
836 [] => write!(f, "invalid choice")?,
837 [ref choice] => write!(f, "expected {}", choice)?,
838 _ => {
839 write!(f, "expected one of ")?;
840 for (i, choice) in choices.iter().enumerate() {
841 if i != 0 { write!(f, ", ")?; }
842 write!(f, "`{}`", choice)?;
843 }
844 }
845 }
846 }
847 ErrorKind::OutOfRange { start, end } => {
848 match (start, end) {
849 (None, None) => write!(f, "value is out of range")?,
850 (None, Some(k)) => write!(f, "value cannot exceed {}", k)?,
851 (Some(k), None) => write!(f, "value must be at least {}", k)?,
852 (Some(i), Some(j)) => write!(f, "value must be between {} and {}", i, j)?,
853 }
854 }
855 ErrorKind::Validation(msg) => msg.fmt(f)?,
856 ErrorKind::Duplicate => "duplicate".fmt(f)?,
857 ErrorKind::Missing => "missing".fmt(f)?,
858 ErrorKind::Unexpected => "unexpected".fmt(f)?,
859 ErrorKind::Unknown => "unknown internal error".fmt(f)?,
860 ErrorKind::Custom(_, e) => e.fmt(f)?,
861 ErrorKind::Multipart(e) => write!(f, "invalid multipart: {}", e)?,
862 ErrorKind::Utf8(e) => write!(f, "invalid UTF-8: {}", e)?,
863 ErrorKind::Char(e) => write!(f, "invalid character: {}", e)?,
864 ErrorKind::Int(e) => write!(f, "invalid integer: {}", e)?,
865 ErrorKind::Bool(e) => write!(f, "invalid boolean: {}", e)?,
866 ErrorKind::Float(e) => write!(f, "invalid float: {}", e)?,
867 ErrorKind::Addr(e) => write!(f, "invalid address: {}", e)?,
868 ErrorKind::Io(e) => write!(f, "i/o error: {}", e)?,
869 }
870
871 Ok(())
872 }
873}
874
875impl crate::http::ext::IntoOwned for ErrorKind<'_> {
876 type Owned = ErrorKind<'static>;
877
878 fn into_owned(self) -> Self::Owned {
879 use ErrorKind::*;
880
881 match self {
882 InvalidLength { min, max } => InvalidLength { min, max },
883 OutOfRange { start, end } => OutOfRange { start, end },
884 Validation(s) => Validation(s.into_owned().into()),
885 Duplicate => Duplicate,
886 Missing => Missing,
887 Unexpected => Unexpected,
888 Unknown => Unknown,
889 Custom(s, e) => Custom(s, e),
890 Multipart(e) => Multipart(e),
891 Utf8(e) => Utf8(e),
892 Char(e) => Char(e),
893 Int(e) => Int(e),
894 Bool(e) => Bool(e),
895 Float(e) => Float(e),
896 Addr(e) => Addr(e),
897 Io(e) => Io(e),
898 InvalidChoice { choices } => InvalidChoice {
899 choices: choices.iter()
900 .map(|s| Cow::Owned(s.to_string()))
901 .collect::<Vec<_>>()
902 .into()
903 }
904 }
905 }
906}
907
908impl<'a, 'b> PartialEq<ErrorKind<'b>> for ErrorKind<'a> {
909 fn eq(&self, other: &ErrorKind<'b>) -> bool {
910 use ErrorKind::*;
911 match (self, other) {
912 (InvalidLength { min: a, max: b }, InvalidLength { min, max }) => min == a && max == b,
913 (InvalidChoice { choices: a }, InvalidChoice { choices }) => choices == a,
914 (OutOfRange { start: a, end: b }, OutOfRange { start, end }) => start == a && end == b,
915 (Validation(a), Validation(b)) => a == b,
916 (Duplicate, Duplicate) => true,
917 (Missing, Missing) => true,
918 (Unexpected, Unexpected) => true,
919 (Custom(a, _), Custom(b, _)) => a == b,
920 (Multipart(a), Multipart(b)) => a == b,
921 (Utf8(a), Utf8(b)) => a == b,
922 (Int(a), Int(b)) => a == b,
923 (Bool(a), Bool(b)) => a == b,
924 (Float(a), Float(b)) => a == b,
925 (Addr(a), Addr(b)) => a == b,
926 (Io(a), Io(b)) => a.kind() == b.kind(),
927 _ => false,
928 }
929 }
930}
931
932impl From<(Option<u64>, Option<u64>)> for ErrorKind<'_> {
933 fn from((min, max): (Option<u64>, Option<u64>)) -> Self {
934 ErrorKind::InvalidLength { min, max }
935 }
936}
937
938impl<'a, 'v: 'a> From<&'static [Cow<'v, str>]> for ErrorKind<'a> {
939 fn from(choices: &'static [Cow<'v, str>]) -> Self {
940 ErrorKind::InvalidChoice { choices: choices.into() }
941 }
942}
943
944impl<'a, 'v: 'a> From<Vec<Cow<'v, str>>> for ErrorKind<'a> {
945 fn from(choices: Vec<Cow<'v, str>>) -> Self {
946 ErrorKind::InvalidChoice { choices: choices.into() }
947 }
948}
949
950impl From<(Option<isize>, Option<isize>)> for ErrorKind<'_> {
951 fn from((start, end): (Option<isize>, Option<isize>)) -> Self {
952 ErrorKind::OutOfRange { start, end }
953 }
954}
955
956impl From<(Option<ByteUnit>, Option<ByteUnit>)> for ErrorKind<'_> {
957 fn from((start, end): (Option<ByteUnit>, Option<ByteUnit>)) -> Self {
958 ErrorKind::from((start.map(ByteUnit::as_u64), end.map(ByteUnit::as_u64)))
959 }
960}
961
962impl<'a, 'v: 'a, const N: usize> From<&'static [Cow<'v, str>; N]> for ErrorKind<'a> {
963 fn from(choices: &'static [Cow<'v, str>; N]) -> Self {
964 let choices = &choices[..];
965 ErrorKind::InvalidChoice { choices: choices.into() }
966 }
967}
968
969impl<'a> From<Box<dyn std::error::Error + Send>> for ErrorKind<'a> {
970 fn from(e: Box<dyn std::error::Error + Send>) -> Self {
971 ErrorKind::Custom(Status::UnprocessableEntity, e)
972 }
973}
974
975impl<'a> From<(Status, Box<dyn std::error::Error + Send>)> for ErrorKind<'a> {
976 fn from((status, e): (Status, Box<dyn std::error::Error + Send>)) -> Self {
977 ErrorKind::Custom(status, e)
978 }
979}
980
981macro_rules! impl_from_for {
982 (<$l:lifetime> $T:ty => $V:ty as $variant:ident) => (
983 impl<$l> From<$T> for $V {
984 fn from(value: $T) -> Self {
985 <$V>::$variant(value)
986 }
987 }
988 )
989}
990
991impl_from_for!(<'a> Utf8Error => ErrorKind<'a> as Utf8);
992impl_from_for!(<'a> ParseIntError => ErrorKind<'a> as Int);
993impl_from_for!(<'a> ParseCharError => ErrorKind<'a> as Char);
994impl_from_for!(<'a> ParseFloatError => ErrorKind<'a> as Float);
995impl_from_for!(<'a> ParseBoolError => ErrorKind<'a> as Bool);
996impl_from_for!(<'a> AddrParseError => ErrorKind<'a> as Addr);
997impl_from_for!(<'a> io::Error => ErrorKind<'a> as Io);
998
999impl fmt::Display for Entity {
1000 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1001 let string = match self {
1002 Entity::Form => "form",
1003 Entity::Field => "field",
1004 Entity::ValueField => "value field",
1005 Entity::DataField => "data field",
1006 Entity::Name => "name",
1007 Entity::Value => "value",
1008 Entity::Key => "key",
1009 Entity::Index(k) => return write!(f, "index {}", k),
1010 };
1011
1012 string.fmt(f)
1013 }
1014}
1015
1016impl Entity {
1017 /// The default entity for an [`Error`] created for `ErrorKind`.
1018 ///
1019 /// * **[`Field`]** if `Duplicate`, `Missing`, `Unexpected`, or `Unknown`
1020 /// * **[`Form`]** if `Multipart` or `Io`
1021 /// * **[`Value`]** otherwise
1022 ///
1023 /// [`Field`]: Entity::Field
1024 /// [`Form`]: Entity::Form
1025 /// [`Value`]: Entity::Value
1026 pub const fn default_for(kind: &ErrorKind<'_>) -> Self {
1027 match kind {
1028 | ErrorKind::InvalidLength { .. }
1029 | ErrorKind::InvalidChoice { .. }
1030 | ErrorKind::OutOfRange { .. }
1031 | ErrorKind::Validation { .. }
1032 | ErrorKind::Utf8(_)
1033 | ErrorKind::Char(_)
1034 | ErrorKind::Int(_)
1035 | ErrorKind::Float(_)
1036 | ErrorKind::Bool(_)
1037 | ErrorKind::Custom(..)
1038 | ErrorKind::Addr(_) => Entity::Value,
1039
1040 | ErrorKind::Duplicate
1041 | ErrorKind::Missing
1042 | ErrorKind::Unknown
1043 | ErrorKind::Unexpected => Entity::Field,
1044
1045 | ErrorKind::Multipart(_)
1046 | ErrorKind::Io(_) => Entity::Form,
1047 }
1048 }
1049}