-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
144 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,99 @@ | ||
use derive_more::Display; | ||
use std::fmt::{self, Debug, Display, Formatter}; | ||
|
||
/// The error type used by the `multer` library. | ||
#[derive(Clone, PartialEq, Eq)] | ||
pub struct Error { | ||
msg: String, | ||
} | ||
type BoxError = Box<dyn std::error::Error + Send + Sync>; | ||
|
||
impl Error { | ||
/// Creates a new error instance with the specified message. | ||
pub fn new<M: Into<String>>(msg: M) -> Self { | ||
Error { msg: msg.into() } | ||
} | ||
/// A set of errors that can occur during parsing multipart stream and in other operations. | ||
#[derive(Display)] | ||
#[display(fmt = "multer: {}")] | ||
pub enum Error { | ||
/// An unknown field is detected when multipart [`constraints`](./struct.Constraints.html#method.allowed_fields) are added. | ||
#[display( | ||
fmt = "An unknown field is detected: {}", | ||
"field_name.as_deref().unwrap_or(\"<unknown>\")" | ||
)] | ||
UnknownField { field_name: Option<String> }, | ||
|
||
/// Converts other error type to the `multer::Error` type. | ||
pub fn wrap<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self { | ||
Error { msg: err.to_string() } | ||
} | ||
} | ||
/// The field data is found incomplete. | ||
#[display( | ||
fmt = "Incomplete field data for field: {}", | ||
"field_name.as_deref().unwrap_or(\"<unknown>\")" | ||
)] | ||
IncompleteFieldData { field_name: Option<String> }, | ||
|
||
impl Display for Error { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | ||
write!(f, "multer: {}", self.msg) | ||
} | ||
} | ||
/// Couldn't read the field headers completely. | ||
#[display(fmt = "Incomplete headers, couldn't read the field headers completely")] | ||
IncompleteHeaders, | ||
|
||
impl Debug for Error { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | ||
write!(f, "multer: {}", self.msg) | ||
} | ||
} | ||
/// Failed to read headers. | ||
#[display(fmt = "Failed to read headers")] | ||
ReadHeaderFailed(BoxError), | ||
|
||
impl std::error::Error for Error { | ||
fn description(&self) -> &str { | ||
self.msg.as_str() | ||
} | ||
} | ||
/// Failed to decode the field's raw header name to [`HeaderName`](https://docs.rs/http/0.2.1/http/header/struct.HeaderName.html) type. | ||
#[display(fmt = "Failed to decode the field's raw header name: {}", cause)] | ||
DecodeHeaderName { name: String, cause: BoxError }, | ||
|
||
pub trait ErrorExt { | ||
fn wrap(self) -> Error; | ||
fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Error; | ||
} | ||
/// Failed to decode the field's raw header value to [`HeaderValue`](https://docs.rs/http/0.2.1/http/header/struct.HeaderValue.html) type. | ||
#[display(fmt = "Failed to decode the field's raw header value: {}", cause)] | ||
DecodeHeaderValue { value: Vec<u8>, cause: BoxError }, | ||
|
||
impl<E: std::error::Error + Send + Sync + 'static> ErrorExt for E { | ||
fn wrap(self) -> Error { | ||
Error { msg: self.to_string() } | ||
} | ||
/// Multipart stream is incomplete. | ||
#[display(fmt = "Multipart stream is incomplete")] | ||
IncompleteStream, | ||
|
||
fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Error { | ||
let msg = format!("{}: {}", ctx, self.to_string()); | ||
Error { msg } | ||
} | ||
} | ||
/// The incoming field size exceeded the maximum limit. | ||
#[display( | ||
fmt = "Incoming field size exceeded the maximum limit: {} bytes, field name: {}", | ||
limit, | ||
"field_name.as_deref().unwrap_or(\"<unknown>\")" | ||
)] | ||
FieldSizeExceeded { limit: usize, field_name: Option<String> }, | ||
|
||
/// The incoming stream size exceeded the maximum limit. | ||
#[display(fmt = "Stream size exceeded the maximum limit: {} bytes", limit)] | ||
StreamSizeExceeded { limit: usize }, | ||
|
||
/// Stream read failed. | ||
#[display(fmt = "Stream read failed")] | ||
StreamReadFailed(BoxError), | ||
|
||
/// Failed to lock the multipart shared state for any changes. | ||
#[display(fmt = "Couldn't lock the multipart state: {}", _0)] | ||
LockFailure(BoxError), | ||
|
||
/// The `Content-Type` header is not `multipart/form-data`. | ||
#[display(fmt = "The Content-Type is not multipart/form-data")] | ||
NoMultipart, | ||
|
||
/// Failed to convert the `Content-Type` to [`mime::Mime`](https://docs.rs/mime/0.3.16/mime/struct.Mime.html) type. | ||
#[display(fmt = "Failed to convert the Content-Type to `mime::Mime` type: {}", _0)] | ||
DecodeContentType(BoxError), | ||
|
||
pub trait ResultExt<T> { | ||
fn wrap(self) -> Result<T, Error>; | ||
fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Result<T, Error>; | ||
/// No boundary found in `Content-Type` header. | ||
#[display(fmt = "No boundary found in Content-Type header")] | ||
NoBoundary, | ||
|
||
/// Failed to decode the field data as `JSON` in [`field.json()`](./struct.Field.html#method.json) method. | ||
#[cfg(feature = "json")] | ||
#[display(fmt = "Failed to decode the field data as JSON")] | ||
DecodeJson(BoxError), | ||
|
||
#[doc(hidden)] | ||
__Nonexhaustive, | ||
} | ||
|
||
impl<T, E: std::error::Error + Send + Sync + 'static> ResultExt<T> for Result<T, E> { | ||
fn wrap(self) -> Result<T, Error> { | ||
self.map_err(|e| e.wrap()) | ||
impl Debug for Error { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { | ||
Display::fmt(self, f) | ||
} | ||
} | ||
|
||
impl std::error::Error for Error {} | ||
|
||
fn context<C: Display + Send + Sync + 'static>(self, ctx: C) -> Result<T, Error> { | ||
match self { | ||
Ok(val) => Ok(val), | ||
Err(err) => Err(err.context(ctx)), | ||
} | ||
impl PartialEq for Error { | ||
fn eq(&self, other: &Self) -> bool { | ||
self.to_string().eq(&other.to_string()) | ||
} | ||
} | ||
|
||
impl Eq for Error {} |
Oops, something went wrong.