2019-03-09 23:06:24 +01:00
|
|
|
//! Error and Result module
|
2019-03-09 16:39:34 +01:00
|
|
|
pub use actix_http::error::*;
|
|
|
|
use derive_more::{Display, From};
|
2019-03-17 08:48:40 +01:00
|
|
|
use serde_json::error::Error as JsonError;
|
2019-03-09 16:39:34 +01:00
|
|
|
use url::ParseError as UrlParseError;
|
|
|
|
|
2019-03-17 08:48:40 +01:00
|
|
|
use crate::http::StatusCode;
|
|
|
|
use crate::HttpResponse;
|
2019-05-14 22:54:30 +02:00
|
|
|
use serde_urlencoded::de;
|
2019-03-17 08:48:40 +01:00
|
|
|
|
2019-03-09 16:39:34 +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,
|
|
|
|
/// Not all path pattern covered
|
|
|
|
#[display(fmt = "Not all path pattern covered")]
|
|
|
|
NotEnoughElements,
|
|
|
|
/// URL parse error
|
|
|
|
#[display(fmt = "{}", _0)]
|
|
|
|
ParseError(UrlParseError),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// `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, From)]
|
|
|
|
pub enum UrlencodedError {
|
|
|
|
/// Can not decode chunked transfer encoding
|
|
|
|
#[display(fmt = "Can not decode chunked transfer encoding")]
|
|
|
|
Chunked,
|
|
|
|
/// Payload size is bigger than allowed. (default: 256kB)
|
2019-04-10 21:43:31 +02:00
|
|
|
#[display(fmt = "Urlencoded payload size is bigger than allowed (default: 256kB)")]
|
2019-03-17 08:48:40 +01:00
|
|
|
Overflow,
|
|
|
|
/// 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")]
|
|
|
|
Parse,
|
|
|
|
/// Payload error
|
|
|
|
#[display(fmt = "Error that occur during reading payload: {}", _0)]
|
|
|
|
Payload(PayloadError),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return `BadRequest` for `UrlencodedError`
|
|
|
|
impl ResponseError for UrlencodedError {
|
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
match *self {
|
|
|
|
UrlencodedError::Overflow => {
|
|
|
|
HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE)
|
|
|
|
}
|
|
|
|
UrlencodedError::UnknownLength => {
|
|
|
|
HttpResponse::new(StatusCode::LENGTH_REQUIRED)
|
|
|
|
}
|
|
|
|
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
2019-04-10 21:43:31 +02:00
|
|
|
#[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),
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
JsonPayloadError::Overflow => {
|
|
|
|
HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE)
|
|
|
|
}
|
|
|
|
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-12 12:49:56 +02:00
|
|
|
/// A set of errors that can occur during parsing request paths
|
|
|
|
#[derive(Debug, Display, From)]
|
2019-06-12 13:02:45 +02:00
|
|
|
pub enum PathError {
|
2019-06-12 12:49:56 +02:00
|
|
|
/// Deserialize error
|
|
|
|
#[display(fmt = "Path deserialize error: {}", _0)]
|
|
|
|
Deserialize(de::Error),
|
|
|
|
}
|
|
|
|
|
2019-06-12 13:02:45 +02:00
|
|
|
/// Return `BadRequest` for `PathError`
|
|
|
|
impl ResponseError for PathError {
|
2019-06-12 12:49:56 +02:00
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
match *self {
|
2019-06-12 13:02:45 +02:00
|
|
|
PathError::Deserialize(_) => HttpResponse::new(StatusCode::BAD_REQUEST),
|
2019-06-12 12:49:56 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-14 22:54:30 +02:00
|
|
|
/// A set of errors that can occur during parsing query strings
|
|
|
|
#[derive(Debug, Display, From)]
|
|
|
|
pub enum QueryPayloadError {
|
|
|
|
/// Deserialize error
|
|
|
|
#[display(fmt = "Query deserialize error: {}", _0)]
|
|
|
|
Deserialize(de::Error),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return `BadRequest` for `QueryPayloadError`
|
|
|
|
impl ResponseError for QueryPayloadError {
|
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
match *self {
|
2019-05-15 19:31:40 +02:00
|
|
|
QueryPayloadError::Deserialize(_) => {
|
|
|
|
HttpResponse::new(StatusCode::BAD_REQUEST)
|
|
|
|
}
|
2019-05-14 22:54:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return `BadRequest` for `ReadlinesError`
|
|
|
|
impl ResponseError for ReadlinesError {
|
|
|
|
fn error_response(&self) -> HttpResponse {
|
|
|
|
match *self {
|
|
|
|
ReadlinesError::LimitOverflow => {
|
|
|
|
HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE)
|
|
|
|
}
|
|
|
|
_ => HttpResponse::new(StatusCode::BAD_REQUEST),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-17 18:11:10 +01:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_urlencoded_error() {
|
|
|
|
let resp: HttpResponse = UrlencodedError::Overflow.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);
|
|
|
|
}
|
|
|
|
|
2019-05-14 22:54:30 +02:00
|
|
|
#[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();
|
2019-05-14 22:54:30 +02:00
|
|
|
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
|
|
|
|
}
|
|
|
|
|
2019-03-17 18:11:10 +01:00
|
|
|
#[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);
|
|
|
|
}
|
|
|
|
}
|