1use actix_web::{
4 error::{ParseError, PayloadError},
5 http::StatusCode,
6 ResponseError,
7};
8use derive_more::{Display, Error, From};
9
10#[derive(Debug, Display, From, Error)]
12#[non_exhaustive]
13pub enum Error {
14 #[display(fmt = "Could not find Content-Type header")]
16 ContentTypeMissing,
17
18 #[display(fmt = "Could not parse Content-Type header")]
20 ContentTypeParse,
21
22 #[display(fmt = "Parsed Content-Type did not have "multipart" top-level media type")]
29 ContentTypeIncompatible,
30
31 #[display(fmt = "Multipart boundary is not found")]
33 BoundaryMissing,
34
35 #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")]
43 ContentDispositionMissing,
44
45 #[display(fmt = "Content-Disposition header was not found when parsing a \"form-data\" field")]
52 ContentDispositionNameMissing,
53
54 #[display(fmt = "Nested multipart is not supported")]
56 Nested,
57
58 #[display(fmt = "Multipart stream is incomplete")]
60 Incomplete,
61
62 #[display(fmt = "Error during field parsing")]
64 Parse(ParseError),
65
66 #[display(fmt = "Payload error")]
68 Payload(PayloadError),
69
70 #[display(fmt = "Stream is not consumed")]
72 NotConsumed,
73
74 #[display(fmt = "An error occurred processing field: {name}")]
76 Field {
77 name: String,
78 source: actix_web::Error,
79 },
80
81 #[display(fmt = "Duplicate field found: {_0}")]
83 #[from(ignore)]
84 DuplicateField(#[error(not(source))] String),
85
86 #[display(fmt = "Required field is missing: {_0}")]
88 #[from(ignore)]
89 MissingField(#[error(not(source))] String),
90
91 #[display(fmt = "Unknown field: {_0}")]
93 #[from(ignore)]
94 UnknownField(#[error(not(source))] String),
95}
96
97impl ResponseError for Error {
99 fn status_code(&self) -> StatusCode {
100 match &self {
101 Error::Field { source, .. } => source.as_response_error().status_code(),
102 Error::ContentTypeIncompatible => StatusCode::UNSUPPORTED_MEDIA_TYPE,
103 _ => StatusCode::BAD_REQUEST,
104 }
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_multipart_error() {
114 let resp = Error::BoundaryMissing.error_response();
115 assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
116 }
117}