mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-01 16:55:08 +02:00
move internalerror to actix web (#2215)
This commit is contained in:
304
src/error/internal.rs
Normal file
304
src/error/internal.rs
Normal file
@ -0,0 +1,304 @@
|
||||
use std::{cell::RefCell, fmt, io::Write as _};
|
||||
|
||||
use actix_http::{body::Body, header, Response, StatusCode};
|
||||
use bytes::{BufMut as _, BytesMut};
|
||||
|
||||
use crate::{Error, HttpResponse, ResponseError};
|
||||
|
||||
/// Wraps errors to alter the generated response status code.
|
||||
///
|
||||
/// In following example, the `io::Error` is wrapped into `ErrorBadRequest` which will generate a
|
||||
/// response with the 400 Bad Request status code instead of the usual status code generated by
|
||||
/// an `io::Error`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::io;
|
||||
/// # use actix_web::{error, HttpRequest};
|
||||
/// async fn handler_error() -> Result<String, actix_web::Error> {
|
||||
/// let err = io::Error::new(io::ErrorKind::Other, "error");
|
||||
/// Err(error::ErrorBadRequest(err))
|
||||
/// }
|
||||
/// ```
|
||||
pub struct InternalError<T> {
|
||||
cause: T,
|
||||
status: InternalErrorType,
|
||||
}
|
||||
|
||||
enum InternalErrorType {
|
||||
Status(StatusCode),
|
||||
Response(RefCell<Option<HttpResponse>>),
|
||||
}
|
||||
|
||||
impl<T> InternalError<T> {
|
||||
/// Constructs an `InternalError` with given status code.
|
||||
pub fn new(cause: T, status: StatusCode) -> Self {
|
||||
InternalError {
|
||||
cause,
|
||||
status: InternalErrorType::Status(status),
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an `InternalError` with pre-defined response.
|
||||
pub fn from_response(cause: T, response: HttpResponse) -> Self {
|
||||
InternalError {
|
||||
cause,
|
||||
status: InternalErrorType::Response(RefCell::new(Some(response))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for InternalError<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.cause.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Display> fmt::Display for InternalError<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.cause.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ResponseError for InternalError<T>
|
||||
where
|
||||
T: fmt::Debug + fmt::Display,
|
||||
{
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self.status {
|
||||
InternalErrorType::Status(st) => st,
|
||||
InternalErrorType::Response(ref resp) => {
|
||||
if let Some(resp) = resp.borrow().as_ref() {
|
||||
resp.head().status
|
||||
} else {
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> Response<Body> {
|
||||
match self.status {
|
||||
InternalErrorType::Status(status) => {
|
||||
let mut res = Response::new(status);
|
||||
let mut buf = BytesMut::new().writer();
|
||||
let _ = write!(buf, "{}", self);
|
||||
|
||||
res.headers_mut().insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("text/plain; charset=utf-8"),
|
||||
);
|
||||
res.set_body(Body::from(buf.into_inner())).into()
|
||||
}
|
||||
|
||||
InternalErrorType::Response(ref resp) => {
|
||||
if let Some(resp) = resp.borrow_mut().take() {
|
||||
resp.into()
|
||||
} else {
|
||||
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! error_helper {
|
||||
($name:ident, $status:ident) => {
|
||||
paste::paste! {
|
||||
#[doc = "Helper function that wraps any error and generates a `" $status "` response."]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn $name<T>(err: T) -> Error
|
||||
where
|
||||
T: fmt::Debug + fmt::Display + 'static,
|
||||
{
|
||||
InternalError::new(err, StatusCode::$status).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_helper!(ErrorBadRequest, BAD_REQUEST);
|
||||
error_helper!(ErrorUnauthorized, UNAUTHORIZED);
|
||||
error_helper!(ErrorPaymentRequired, PAYMENT_REQUIRED);
|
||||
error_helper!(ErrorForbidden, FORBIDDEN);
|
||||
error_helper!(ErrorNotFound, NOT_FOUND);
|
||||
error_helper!(ErrorMethodNotAllowed, METHOD_NOT_ALLOWED);
|
||||
error_helper!(ErrorNotAcceptable, NOT_ACCEPTABLE);
|
||||
error_helper!(
|
||||
ErrorProxyAuthenticationRequired,
|
||||
PROXY_AUTHENTICATION_REQUIRED
|
||||
);
|
||||
error_helper!(ErrorRequestTimeout, REQUEST_TIMEOUT);
|
||||
error_helper!(ErrorConflict, CONFLICT);
|
||||
error_helper!(ErrorGone, GONE);
|
||||
error_helper!(ErrorLengthRequired, LENGTH_REQUIRED);
|
||||
error_helper!(ErrorPayloadTooLarge, PAYLOAD_TOO_LARGE);
|
||||
error_helper!(ErrorUriTooLong, URI_TOO_LONG);
|
||||
error_helper!(ErrorUnsupportedMediaType, UNSUPPORTED_MEDIA_TYPE);
|
||||
error_helper!(ErrorRangeNotSatisfiable, RANGE_NOT_SATISFIABLE);
|
||||
error_helper!(ErrorImATeapot, IM_A_TEAPOT);
|
||||
error_helper!(ErrorMisdirectedRequest, MISDIRECTED_REQUEST);
|
||||
error_helper!(ErrorUnprocessableEntity, UNPROCESSABLE_ENTITY);
|
||||
error_helper!(ErrorLocked, LOCKED);
|
||||
error_helper!(ErrorFailedDependency, FAILED_DEPENDENCY);
|
||||
error_helper!(ErrorUpgradeRequired, UPGRADE_REQUIRED);
|
||||
error_helper!(ErrorPreconditionFailed, PRECONDITION_FAILED);
|
||||
error_helper!(ErrorPreconditionRequired, PRECONDITION_REQUIRED);
|
||||
error_helper!(ErrorTooManyRequests, TOO_MANY_REQUESTS);
|
||||
error_helper!(
|
||||
ErrorRequestHeaderFieldsTooLarge,
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE
|
||||
);
|
||||
error_helper!(
|
||||
ErrorUnavailableForLegalReasons,
|
||||
UNAVAILABLE_FOR_LEGAL_REASONS
|
||||
);
|
||||
error_helper!(ErrorExpectationFailed, EXPECTATION_FAILED);
|
||||
error_helper!(ErrorInternalServerError, INTERNAL_SERVER_ERROR);
|
||||
error_helper!(ErrorNotImplemented, NOT_IMPLEMENTED);
|
||||
error_helper!(ErrorBadGateway, BAD_GATEWAY);
|
||||
error_helper!(ErrorServiceUnavailable, SERVICE_UNAVAILABLE);
|
||||
error_helper!(ErrorGatewayTimeout, GATEWAY_TIMEOUT);
|
||||
error_helper!(ErrorHttpVersionNotSupported, HTTP_VERSION_NOT_SUPPORTED);
|
||||
error_helper!(ErrorVariantAlsoNegotiates, VARIANT_ALSO_NEGOTIATES);
|
||||
error_helper!(ErrorInsufficientStorage, INSUFFICIENT_STORAGE);
|
||||
error_helper!(ErrorLoopDetected, LOOP_DETECTED);
|
||||
error_helper!(ErrorNotExtended, NOT_EXTENDED);
|
||||
error_helper!(
|
||||
ErrorNetworkAuthenticationRequired,
|
||||
NETWORK_AUTHENTICATION_REQUIRED
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::{error::ParseError, Response};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_internal_error() {
|
||||
let err = InternalError::from_response(ParseError::Method, HttpResponse::Ok().finish());
|
||||
let resp: Response<Body> = err.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_helpers() {
|
||||
let res: Response<Body> = ErrorBadRequest("err").into();
|
||||
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let res: Response<Body> = ErrorUnauthorized("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
|
||||
|
||||
let res: Response<Body> = ErrorPaymentRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PAYMENT_REQUIRED);
|
||||
|
||||
let res: Response<Body> = ErrorForbidden("err").into();
|
||||
assert_eq!(res.status(), StatusCode::FORBIDDEN);
|
||||
|
||||
let res: Response<Body> = ErrorNotFound("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let res: Response<Body> = ErrorMethodNotAllowed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);
|
||||
|
||||
let res: Response<Body> = ErrorNotAcceptable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_ACCEPTABLE);
|
||||
|
||||
let res: Response<Body> = ErrorProxyAuthenticationRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
|
||||
|
||||
let res: Response<Body> = ErrorRequestTimeout("err").into();
|
||||
assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
|
||||
|
||||
let res: Response<Body> = ErrorConflict("err").into();
|
||||
assert_eq!(res.status(), StatusCode::CONFLICT);
|
||||
|
||||
let res: Response<Body> = ErrorGone("err").into();
|
||||
assert_eq!(res.status(), StatusCode::GONE);
|
||||
|
||||
let res: Response<Body> = ErrorLengthRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LENGTH_REQUIRED);
|
||||
|
||||
let res: Response<Body> = ErrorPreconditionFailed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PRECONDITION_FAILED);
|
||||
|
||||
let res: Response<Body> = ErrorPayloadTooLarge("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
|
||||
let res: Response<Body> = ErrorUriTooLong("err").into();
|
||||
assert_eq!(res.status(), StatusCode::URI_TOO_LONG);
|
||||
|
||||
let res: Response<Body> = ErrorUnsupportedMediaType("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
|
||||
|
||||
let res: Response<Body> = ErrorRangeNotSatisfiable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::RANGE_NOT_SATISFIABLE);
|
||||
|
||||
let res: Response<Body> = ErrorExpectationFailed("err").into();
|
||||
assert_eq!(res.status(), StatusCode::EXPECTATION_FAILED);
|
||||
|
||||
let res: Response<Body> = ErrorImATeapot("err").into();
|
||||
assert_eq!(res.status(), StatusCode::IM_A_TEAPOT);
|
||||
|
||||
let res: Response<Body> = ErrorMisdirectedRequest("err").into();
|
||||
assert_eq!(res.status(), StatusCode::MISDIRECTED_REQUEST);
|
||||
|
||||
let res: Response<Body> = ErrorUnprocessableEntity("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);
|
||||
|
||||
let res: Response<Body> = ErrorLocked("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LOCKED);
|
||||
|
||||
let res: Response<Body> = ErrorFailedDependency("err").into();
|
||||
assert_eq!(res.status(), StatusCode::FAILED_DEPENDENCY);
|
||||
|
||||
let res: Response<Body> = ErrorUpgradeRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UPGRADE_REQUIRED);
|
||||
|
||||
let res: Response<Body> = ErrorPreconditionRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::PRECONDITION_REQUIRED);
|
||||
|
||||
let res: Response<Body> = ErrorTooManyRequests("err").into();
|
||||
assert_eq!(res.status(), StatusCode::TOO_MANY_REQUESTS);
|
||||
|
||||
let res: Response<Body> = ErrorRequestHeaderFieldsTooLarge("err").into();
|
||||
assert_eq!(res.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
|
||||
|
||||
let res: Response<Body> = ErrorUnavailableForLegalReasons("err").into();
|
||||
assert_eq!(res.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
|
||||
|
||||
let res: Response<Body> = ErrorInternalServerError("err").into();
|
||||
assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
|
||||
|
||||
let res: Response<Body> = ErrorNotImplemented("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_IMPLEMENTED);
|
||||
|
||||
let res: Response<Body> = ErrorBadGateway("err").into();
|
||||
assert_eq!(res.status(), StatusCode::BAD_GATEWAY);
|
||||
|
||||
let res: Response<Body> = ErrorServiceUnavailable("err").into();
|
||||
assert_eq!(res.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
|
||||
let res: Response<Body> = ErrorGatewayTimeout("err").into();
|
||||
assert_eq!(res.status(), StatusCode::GATEWAY_TIMEOUT);
|
||||
|
||||
let res: Response<Body> = ErrorHttpVersionNotSupported("err").into();
|
||||
assert_eq!(res.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
|
||||
|
||||
let res: Response<Body> = ErrorVariantAlsoNegotiates("err").into();
|
||||
assert_eq!(res.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
|
||||
|
||||
let res: Response<Body> = ErrorInsufficientStorage("err").into();
|
||||
assert_eq!(res.status(), StatusCode::INSUFFICIENT_STORAGE);
|
||||
|
||||
let res: Response<Body> = ErrorLoopDetected("err").into();
|
||||
assert_eq!(res.status(), StatusCode::LOOP_DETECTED);
|
||||
|
||||
let res: Response<Body> = ErrorNotExtended("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NOT_EXTENDED);
|
||||
|
||||
let res: Response<Body> = ErrorNetworkAuthenticationRequired("err").into();
|
||||
assert_eq!(res.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
|
||||
}
|
||||
}
|
233
src/error/mod.rs
Normal file
233
src/error/mod.rs
Normal file
@ -0,0 +1,233 @@
|
||||
//! Error and Result module
|
||||
|
||||
pub use actix_http::error::*;
|
||||
use derive_more::{Display, Error, From};
|
||||
use serde_json::error::Error as JsonError;
|
||||
use serde_urlencoded::de::Error as FormDeError;
|
||||
use serde_urlencoded::ser::Error as FormError;
|
||||
use url::ParseError as UrlParseError;
|
||||
|
||||
use crate::http::StatusCode;
|
||||
|
||||
mod internal;
|
||||
|
||||
pub use self::internal::*;
|
||||
|
||||
/// A convenience [`Result`](std::result::Result) for Actix Web operations.
|
||||
///
|
||||
/// This type alias is generally used to avoid writing out `actix_http::Error` directly.
|
||||
pub type Result<T, E = actix_http::Error> = std::result::Result<T, E>;
|
||||
|
||||
/// Errors which can occur when attempting to generate resource uri.
|
||||
#[derive(Debug, PartialEq, Display, Error, From)]
|
||||
#[non_exhaustive]
|
||||
pub enum UrlGenerationError {
|
||||
/// Resource not found
|
||||
#[display(fmt = "Resource not found")]
|
||||
ResourceNotFound,
|
||||
|
||||
/// Not all path pattern covered
|
||||
#[display(fmt = "Not all path pattern covered")]
|
||||
NotEnoughElements,
|
||||
|
||||
/// URL parse error
|
||||
#[display(fmt = "{}", _0)]
|
||||
ParseError(UrlParseError),
|
||||
}
|
||||
|
||||
impl ResponseError for UrlGenerationError {}
|
||||
|
||||
/// A set of errors that can occur during parsing urlencoded payloads
|
||||
#[derive(Debug, Display, Error, From)]
|
||||
#[non_exhaustive]
|
||||
pub enum UrlencodedError {
|
||||
/// Can not decode chunked transfer encoding.
|
||||
#[display(fmt = "Can not decode chunked transfer encoding.")]
|
||||
Chunked,
|
||||
|
||||
/// Payload size is larger than allowed. (default limit: 256kB).
|
||||
#[display(
|
||||
fmt = "URL encoded payload is larger ({} bytes) than allowed (limit: {} bytes).",
|
||||
size,
|
||||
limit
|
||||
)]
|
||||
Overflow { size: usize, limit: usize },
|
||||
|
||||
/// Payload size is now known.
|
||||
#[display(fmt = "Payload size is now known.")]
|
||||
UnknownLength,
|
||||
|
||||
/// Content type error.
|
||||
#[display(fmt = "Content type error.")]
|
||||
ContentType,
|
||||
|
||||
/// Parse error.
|
||||
#[display(fmt = "Parse error: {}.", _0)]
|
||||
Parse(FormDeError),
|
||||
|
||||
/// Encoding error.
|
||||
#[display(fmt = "Encoding error.")]
|
||||
Encoding,
|
||||
|
||||
/// Serialize error.
|
||||
#[display(fmt = "Serialize error: {}.", _0)]
|
||||
Serialize(FormError),
|
||||
|
||||
/// Payload error.
|
||||
#[display(fmt = "Error that occur during reading payload: {}.", _0)]
|
||||
Payload(PayloadError),
|
||||
}
|
||||
|
||||
impl ResponseError for UrlencodedError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
Self::Overflow { .. } => StatusCode::PAYLOAD_TOO_LARGE,
|
||||
Self::UnknownLength => StatusCode::LENGTH_REQUIRED,
|
||||
Self::Payload(err) => err.status_code(),
|
||||
_ => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of errors that can occur during parsing json payloads
|
||||
#[derive(Debug, Display, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum JsonPayloadError {
|
||||
/// Payload size is bigger than allowed. (default: 32kB)
|
||||
#[display(fmt = "Json payload size is bigger than allowed")]
|
||||
Overflow,
|
||||
|
||||
/// Content type error
|
||||
#[display(fmt = "Content type error")]
|
||||
ContentType,
|
||||
|
||||
/// Deserialize error
|
||||
#[display(fmt = "Json deserialize error: {}", _0)]
|
||||
Deserialize(JsonError),
|
||||
|
||||
/// Serialize error
|
||||
#[display(fmt = "Json serialize error: {}", _0)]
|
||||
Serialize(JsonError),
|
||||
|
||||
/// Payload error
|
||||
#[display(fmt = "Error that occur during reading payload: {}", _0)]
|
||||
Payload(PayloadError),
|
||||
}
|
||||
|
||||
impl From<PayloadError> for JsonPayloadError {
|
||||
fn from(err: PayloadError) -> Self {
|
||||
Self::Payload(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseError for JsonPayloadError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
Self::Overflow => StatusCode::PAYLOAD_TOO_LARGE,
|
||||
Self::Serialize(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Self::Payload(err) => err.status_code(),
|
||||
_ => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of errors that can occur during parsing request paths
|
||||
#[derive(Debug, Display, Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum PathError {
|
||||
/// Deserialize error
|
||||
#[display(fmt = "Path deserialize error: {}", _0)]
|
||||
Deserialize(serde::de::value::Error),
|
||||
}
|
||||
|
||||
/// Return `BadRequest` for `PathError`
|
||||
impl ResponseError for PathError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of errors that can occur during parsing query strings.
|
||||
#[derive(Debug, Display, Error, From)]
|
||||
#[non_exhaustive]
|
||||
pub enum QueryPayloadError {
|
||||
/// Query deserialize error.
|
||||
#[display(fmt = "Query deserialize error: {}", _0)]
|
||||
Deserialize(serde::de::value::Error),
|
||||
}
|
||||
|
||||
impl ResponseError for QueryPayloadError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type returned when reading body as lines.
|
||||
#[derive(Debug, Display, Error, From)]
|
||||
#[non_exhaustive]
|
||||
pub enum ReadlinesError {
|
||||
#[display(fmt = "Encoding error")]
|
||||
/// Payload size is bigger than allowed. (default: 256kB)
|
||||
EncodingError,
|
||||
|
||||
/// Payload error.
|
||||
#[display(fmt = "Error that occur during reading payload: {}", _0)]
|
||||
Payload(PayloadError),
|
||||
|
||||
/// Line limit exceeded.
|
||||
#[display(fmt = "Line limit exceeded")]
|
||||
LimitOverflow,
|
||||
|
||||
/// ContentType error.
|
||||
#[display(fmt = "Content-type error")]
|
||||
ContentTypeError(ContentTypeError),
|
||||
}
|
||||
|
||||
impl ResponseError for ReadlinesError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
ReadlinesError::LimitOverflow => StatusCode::PAYLOAD_TOO_LARGE,
|
||||
_ => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_urlencoded_error() {
|
||||
let resp = UrlencodedError::Overflow { size: 0, limit: 0 }.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
let resp = UrlencodedError::UnknownLength.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::LENGTH_REQUIRED);
|
||||
let resp = UrlencodedError::ContentType.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_payload_error() {
|
||||
let resp = JsonPayloadError::Overflow.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
let resp = JsonPayloadError::ContentType.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_payload_error() {
|
||||
let resp = QueryPayloadError::Deserialize(
|
||||
serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
|
||||
)
|
||||
.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_readlines_error() {
|
||||
let resp = ReadlinesError::LimitOverflow.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
|
||||
let resp = ReadlinesError::EncodingError.error_response();
|
||||
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user