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}