2019-04-03 19:28:58 +00:00
|
|
|
//! Error and Result module
|
2023-02-26 03:26:06 +00:00
|
|
|
|
|
|
|
use actix_web::{
|
|
|
|
error::{ParseError, PayloadError},
|
|
|
|
http::StatusCode,
|
|
|
|
ResponseError,
|
|
|
|
};
|
2021-11-17 17:43:24 +00:00
|
|
|
use derive_more::{Display, Error, From};
|
2019-04-03 19:28:58 +00:00
|
|
|
|
2023-02-26 03:26:06 +00:00
|
|
|
/// A set of errors that can occur during parsing multipart streams.
|
2021-11-17 17:43:24 +00:00
|
|
|
#[derive(Debug, Display, From, Error)]
|
2023-02-26 03:26:06 +00:00
|
|
|
#[non_exhaustive]
|
2019-04-03 19:28:58 +00:00
|
|
|
pub enum MultipartError {
|
2021-11-17 17:43:24 +00:00
|
|
|
/// Content-Disposition header is not found or is not equal to "form-data".
|
|
|
|
///
|
2021-12-02 03:45:04 +00:00
|
|
|
/// According to [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) a
|
2021-11-17 17:43:24 +00:00
|
|
|
/// Content-Disposition header must always be present and equal to "form-data".
|
|
|
|
#[display(fmt = "No Content-Disposition `form-data` header")]
|
|
|
|
NoContentDisposition,
|
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Content-Type header is not found
|
2021-11-17 17:43:24 +00:00
|
|
|
#[display(fmt = "No Content-Type header found")]
|
2019-04-03 19:28:58 +00:00
|
|
|
NoContentType,
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Can not parse Content-Type header
|
|
|
|
#[display(fmt = "Can not parse Content-Type header")]
|
|
|
|
ParseContentType,
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Multipart boundary is not found
|
|
|
|
#[display(fmt = "Multipart boundary is not found")]
|
|
|
|
Boundary,
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-13 17:11:07 +00:00
|
|
|
/// Nested multipart is not supported
|
|
|
|
#[display(fmt = "Nested multipart is not supported")]
|
|
|
|
Nested,
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Multipart stream is incomplete
|
|
|
|
#[display(fmt = "Multipart stream is incomplete")]
|
|
|
|
Incomplete,
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Error during field parsing
|
|
|
|
#[display(fmt = "{}", _0)]
|
|
|
|
Parse(ParseError),
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-04-03 19:28:58 +00:00
|
|
|
/// Payload error
|
|
|
|
#[display(fmt = "{}", _0)]
|
|
|
|
Payload(PayloadError),
|
2021-11-17 17:43:24 +00:00
|
|
|
|
2019-05-12 18:43:05 +00:00
|
|
|
/// Not consumed
|
|
|
|
#[display(fmt = "Multipart stream is not consumed")]
|
|
|
|
NotConsumed,
|
2023-02-26 03:26:06 +00:00
|
|
|
|
|
|
|
/// An error from a field handler in a form
|
|
|
|
#[display(
|
|
|
|
fmt = "An error occurred processing field `{}`: {}",
|
|
|
|
field_name,
|
|
|
|
source
|
|
|
|
)]
|
|
|
|
Field {
|
|
|
|
field_name: String,
|
|
|
|
source: actix_web::Error,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Duplicate field
|
|
|
|
#[display(fmt = "Duplicate field found for: `{}`", _0)]
|
|
|
|
#[from(ignore)]
|
|
|
|
DuplicateField(#[error(not(source))] String),
|
|
|
|
|
|
|
|
/// Missing field
|
|
|
|
#[display(fmt = "Field with name `{}` is required", _0)]
|
|
|
|
#[from(ignore)]
|
|
|
|
MissingField(#[error(not(source))] String),
|
|
|
|
|
|
|
|
/// Unknown field
|
|
|
|
#[display(fmt = "Unsupported field `{}`", _0)]
|
|
|
|
#[from(ignore)]
|
|
|
|
UnsupportedField(#[error(not(source))] String),
|
2019-04-03 19:28:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Return `BadRequest` for `MultipartError`
|
|
|
|
impl ResponseError for MultipartError {
|
2019-11-26 10:07:39 +00:00
|
|
|
fn status_code(&self) -> StatusCode {
|
2023-02-26 03:26:06 +00:00
|
|
|
match &self {
|
|
|
|
MultipartError::Field { source, .. } => source.as_response_error().status_code(),
|
|
|
|
_ => StatusCode::BAD_REQUEST,
|
|
|
|
}
|
2019-04-03 19:28:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_multipart_error() {
|
2021-04-09 17:07:10 +00:00
|
|
|
let resp = MultipartError::Boundary.error_response();
|
2019-04-03 19:28:58 +00:00
|
|
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
|
|
|
}
|
|
|
|
}
|