1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-30 18:44:35 +01:00
actix-web/src/error.rs

205 lines
6.2 KiB
Rust
Raw Normal View History

//! Error and Result module
2020-11-20 19:02:41 +01:00
pub use actix_http::error::*;
use derive_more::{Display, Error, From};
2019-03-17 08:48:40 +01:00
use serde_json::error::Error as JsonError;
use url::ParseError as UrlParseError;
use crate::{http::StatusCode, HttpResponse};
2019-03-17 08:48:40 +01:00
/// Errors which can occur when attempting to generate resource uri.
#[derive(Debug, PartialEq, Display, From)]
pub enum UrlGenerationError {
/// Resource not found
#[display(fmt = "Resource not found")]
ResourceNotFound,
2021-02-13 16:08:43 +01:00
/// Not all path pattern covered
#[display(fmt = "Not all path pattern covered")]
NotEnoughElements,
2021-02-13 16:08:43 +01:00
/// URL parse error
#[display(fmt = "{}", _0)]
ParseError(UrlParseError),
}
impl std::error::Error for UrlGenerationError {}
/// `InternalServerError` for `UrlGeneratorError`
impl ResponseError for UrlGenerationError {}
2019-03-12 07:19:05 +01:00
2019-03-17 08:48:40 +01:00
/// A set of errors that can occur during parsing urlencoded payloads
#[derive(Debug, Display, Error, From)]
2019-03-17 08:48:40 +01:00
pub enum UrlencodedError {
/// Can not decode chunked transfer encoding.
#[display(fmt = "Can not decode chunked transfer encoding.")]
2019-03-17 08:48:40 +01:00
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.")]
2019-03-17 08:48:40 +01:00
UnknownLength,
/// Content type error.
#[display(fmt = "Content type error.")]
2019-03-17 08:48:40 +01:00
ContentType,
/// Parse error.
#[display(fmt = "Parse error.")]
2019-03-17 08:48:40 +01:00
Parse,
/// Payload error.
#[display(fmt = "Error that occur during reading payload: {}.", _0)]
2019-03-17 08:48:40 +01:00
Payload(PayloadError),
}
/// Return `BadRequest` for `UrlencodedError`
impl ResponseError for UrlencodedError {
2019-11-26 11:07:39 +01:00
fn status_code(&self) -> StatusCode {
2019-03-17 08:48:40 +01:00
match *self {
2019-11-26 11:07:39 +01:00
UrlencodedError::Overflow { .. } => StatusCode::PAYLOAD_TOO_LARGE,
UrlencodedError::UnknownLength => StatusCode::LENGTH_REQUIRED,
_ => StatusCode::BAD_REQUEST,
2019-03-17 08:48:40 +01:00
}
}
}
/// A set of errors that can occur during parsing json payloads
#[derive(Debug, Display, From)]
pub enum JsonPayloadError {
2019-03-17 17:52:41 +01:00
/// Payload size is bigger than allowed. (default: 32kB)
#[display(fmt = "Json payload size is bigger than allowed")]
2019-03-17 08:48:40 +01:00
Overflow,
/// Content type error
#[display(fmt = "Content type error")]
ContentType,
/// Deserialize error
#[display(fmt = "Json deserialize error: {}", _0)]
Deserialize(JsonError),
/// Payload error
#[display(fmt = "Error that occur during reading payload: {}", _0)]
Payload(PayloadError),
}
impl std::error::Error for JsonPayloadError {}
2019-04-01 20:51:18 +02:00
/// Return `BadRequest` for `JsonPayloadError`
2019-03-17 08:48:40 +01:00
impl ResponseError for JsonPayloadError {
fn error_response(&self) -> HttpResponse {
match *self {
2021-02-12 00:03:17 +01:00
JsonPayloadError::Overflow => HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE),
2019-03-17 08:48:40 +01:00
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
}
}
}
/// A set of errors that can occur during parsing request paths
#[derive(Debug, Display, From)]
pub enum PathError {
/// Deserialize error
#[display(fmt = "Path deserialize error: {}", _0)]
2019-12-18 04:30:14 +01:00
Deserialize(serde::de::value::Error),
}
impl std::error::Error for PathError {}
/// Return `BadRequest` for `PathError`
impl ResponseError for PathError {
2019-11-26 11:07:39 +01:00
fn status_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
}
/// A set of errors that can occur during parsing query strings.
#[derive(Debug, Display, Error, From)]
pub enum QueryPayloadError {
/// Query deserialize error.
#[display(fmt = "Query deserialize error: {}", _0)]
2019-12-18 04:30:14 +01:00
Deserialize(serde::de::value::Error),
}
/// Return `BadRequest` for `QueryPayloadError`
impl ResponseError for QueryPayloadError {
2019-11-26 11:07:39 +01:00
fn status_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
}
2019-03-17 08:48:40 +01:00
/// Error type returned when reading body as lines.
#[derive(From, Display, Debug)]
pub enum ReadlinesError {
/// Error when decoding a line.
#[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 std::error::Error for ReadlinesError {}
2019-03-17 08:48:40 +01:00
/// Return `BadRequest` for `ReadlinesError`
impl ResponseError for ReadlinesError {
2019-11-26 11:07:39 +01:00
fn status_code(&self) -> StatusCode {
2019-03-17 08:48:40 +01:00
match *self {
2019-11-26 11:07:39 +01:00
ReadlinesError::LimitOverflow => StatusCode::PAYLOAD_TOO_LARGE,
_ => StatusCode::BAD_REQUEST,
2019-03-17 08:48:40 +01:00
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_urlencoded_error() {
let resp: HttpResponse =
UrlencodedError::Overflow { size: 0, limit: 0 }.error_response();
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
let resp: HttpResponse = UrlencodedError::UnknownLength.error_response();
assert_eq!(resp.status(), StatusCode::LENGTH_REQUIRED);
let resp: HttpResponse = UrlencodedError::ContentType.error_response();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}
#[test]
fn test_json_payload_error() {
let resp: HttpResponse = JsonPayloadError::Overflow.error_response();
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
let resp: HttpResponse = JsonPayloadError::ContentType.error_response();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}
#[test]
fn test_query_payload_error() {
2019-05-15 19:31:40 +02:00
let resp: HttpResponse = 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: HttpResponse = ReadlinesError::LimitOverflow.error_response();
assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
let resp: HttpResponse = ReadlinesError::EncodingError.error_response();
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}
}