use std::fmt::{self, Debug, Display, Formatter};
type BoxError = Box<dyn std::error::Error + Send + Sync>;
#[non_exhaustive]
pub enum Error {
UnknownField { field_name: Option<String> },
IncompleteFieldData { field_name: Option<String> },
IncompleteHeaders,
ReadHeaderFailed(httparse::Error),
DecodeHeaderName { name: String, cause: BoxError },
DecodeHeaderValue { value: Vec<u8>, cause: BoxError },
IncompleteStream,
FieldSizeExceeded { limit: u64, field_name: Option<String> },
StreamSizeExceeded { limit: u64 },
StreamReadFailed(BoxError),
LockFailure,
NoMultipart,
DecodeContentType(mime::FromStrError),
NoBoundary,
#[cfg(feature = "json")]
#[cfg_attr(nightly, doc(cfg(feature = "json")))]
DecodeJson(serde_json::Error),
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(self, f)
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Error::UnknownField { field_name } => {
let name = field_name.as_deref().unwrap_or("<unknown>");
write!(f, "unknown field received: {:?}", name)
}
Error::IncompleteFieldData { field_name } => {
let name = field_name.as_deref().unwrap_or("<unknown>");
write!(f, "field {:?} received with incomplete data", name)
}
Error::DecodeHeaderName { name, cause } => {
write!(f, "failed to decode field's raw header name: {:?} {}", name, cause)
}
Error::DecodeHeaderValue { cause, .. } => {
write!(f, "failed to decode field's raw header value: {}", cause)
}
Error::FieldSizeExceeded { limit, field_name } => {
let name = field_name.as_deref().unwrap_or("<unknown>");
write!(f, "field {:?} exceeded the size limit: {} bytes", name, limit)
}
Error::StreamSizeExceeded { limit } => {
write!(f, "stream size exceeded limit: {} bytes", limit)
}
Error::ReadHeaderFailed(e) => write!(f, "failed to read headers: {}", e),
Error::StreamReadFailed(e) => write!(f, "failed to read stream: {}", e),
Error::DecodeContentType(e) => write!(f, "failed to decode Content-Type: {}", e),
Error::IncompleteHeaders => write!(f, "failed to read field complete headers"),
Error::IncompleteStream => write!(f, "incomplete multipart stream"),
Error::LockFailure => write!(f, "failed to lock multipart state"),
Error::NoMultipart => write!(f, "Content-Type is not multipart/form-data"),
Error::NoBoundary => write!(f, "multipart boundary not found in Content-Type"),
#[cfg(feature = "json")]
Error::DecodeJson(e) => write!(f, "failed to decode field data as JSON: {}", e),
}
}
}
impl std::error::Error for Error {}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
self.to_string().eq(&other.to_string())
}
}
impl Eq for Error {}