mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 16:02:59 +01:00
drop failure crate
This commit is contained in:
parent
b1001b80b7
commit
cc74435b01
13
Cargo.toml
13
Cargo.toml
@ -51,12 +51,13 @@ actix-utils = "0.1.0"
|
|||||||
# actix-utils = { path="../actix-net/actix-utils/" }
|
# actix-utils = { path="../actix-net/actix-utils/" }
|
||||||
|
|
||||||
base64 = "0.9"
|
base64 = "0.9"
|
||||||
|
backtrace = "0.3"
|
||||||
bitflags = "1.0"
|
bitflags = "1.0"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
byteorder = "1.2"
|
byteorder = "1.2"
|
||||||
cookie = { version="0.11", features=["percent-encode"] }
|
cookie = { version="0.11", features=["percent-encode"] }
|
||||||
|
derive_more = "0.13"
|
||||||
encoding = "0.2"
|
encoding = "0.2"
|
||||||
failure = "0.1.3"
|
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
http = "0.1.8"
|
http = "0.1.8"
|
||||||
httparse = "1.3"
|
httparse = "1.3"
|
||||||
@ -74,19 +75,11 @@ serde_urlencoded = "0.5.3"
|
|||||||
time = "0.1"
|
time = "0.1"
|
||||||
tokio-tcp = "0.1"
|
tokio-tcp = "0.1"
|
||||||
tokio-timer = "0.2"
|
tokio-timer = "0.2"
|
||||||
trust-dns-proto = "0.5.0"
|
trust-dns-resolver = "0.10.1"
|
||||||
trust-dns-resolver = "0.10.0"
|
|
||||||
url = { version="1.7", features=["query_encoding"] }
|
|
||||||
|
|
||||||
# native-tls
|
|
||||||
native-tls = { version="0.2", optional = true }
|
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
openssl = { version="0.10", optional = true }
|
openssl = { version="0.10", optional = true }
|
||||||
|
|
||||||
# rustls
|
|
||||||
rustls = { version = "^0.14", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-web = "0.7"
|
actix-web = "0.7"
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use failure::Fail;
|
use derive_more::{Display, From};
|
||||||
use trust_dns_resolver::error::ResolveError;
|
use trust_dns_resolver::error::ResolveError;
|
||||||
|
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
@ -9,71 +9,52 @@ use openssl::ssl::{Error as SslError, HandshakeError};
|
|||||||
use crate::error::{Error, ParseError};
|
use crate::error::{Error, ParseError};
|
||||||
|
|
||||||
/// A set of errors that can occur while connecting to an HTTP host
|
/// A set of errors that can occur while connecting to an HTTP host
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum ConnectorError {
|
pub enum ConnectorError {
|
||||||
/// Invalid URL
|
/// Invalid URL
|
||||||
#[fail(display = "Invalid URL")]
|
#[display(fmt = "Invalid URL")]
|
||||||
InvalidUrl(InvalidUrlKind),
|
InvalidUrl(InvalidUrlKind),
|
||||||
|
|
||||||
/// SSL feature is not enabled
|
/// SSL feature is not enabled
|
||||||
#[fail(display = "SSL is not supported")]
|
#[display(fmt = "SSL is not supported")]
|
||||||
SslIsNotSupported,
|
SslIsNotSupported,
|
||||||
|
|
||||||
/// SSL error
|
/// SSL error
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
#[fail(display = "{}", _0)]
|
#[display(fmt = "{}", _0)]
|
||||||
SslError(#[cause] SslError),
|
SslError(SslError),
|
||||||
|
|
||||||
/// Failed to resolve the hostname
|
/// Failed to resolve the hostname
|
||||||
#[fail(display = "Failed resolving hostname: {}", _0)]
|
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
||||||
Resolver(ResolveError),
|
Resolver(ResolveError),
|
||||||
|
|
||||||
/// No dns records
|
/// No dns records
|
||||||
#[fail(display = "No dns records found for the input")]
|
#[display(fmt = "No dns records found for the input")]
|
||||||
NoRecords,
|
NoRecords,
|
||||||
|
|
||||||
/// Connecting took too long
|
/// Connecting took too long
|
||||||
#[fail(display = "Timeout out while establishing connection")]
|
#[display(fmt = "Timeout out while establishing connection")]
|
||||||
Timeout,
|
Timeout,
|
||||||
|
|
||||||
/// Connector has been disconnected
|
/// Connector has been disconnected
|
||||||
#[fail(display = "Internal error: connector has been disconnected")]
|
#[display(fmt = "Internal error: connector has been disconnected")]
|
||||||
Disconnected,
|
Disconnected,
|
||||||
|
|
||||||
/// Connection io error
|
/// Connection io error
|
||||||
#[fail(display = "{}", _0)]
|
#[display(fmt = "{}", _0)]
|
||||||
IoError(io::Error),
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display)]
|
||||||
pub enum InvalidUrlKind {
|
pub enum InvalidUrlKind {
|
||||||
#[fail(display = "Missing url scheme")]
|
#[display(fmt = "Missing url scheme")]
|
||||||
MissingScheme,
|
MissingScheme,
|
||||||
#[fail(display = "Unknown url scheme")]
|
#[display(fmt = "Unknown url scheme")]
|
||||||
UnknownScheme,
|
UnknownScheme,
|
||||||
#[fail(display = "Missing host name")]
|
#[display(fmt = "Missing host name")]
|
||||||
MissingHost,
|
MissingHost,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for ConnectorError {
|
|
||||||
fn from(err: io::Error) -> ConnectorError {
|
|
||||||
ConnectorError::IoError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ResolveError> for ConnectorError {
|
|
||||||
fn from(err: ResolveError) -> ConnectorError {
|
|
||||||
ConnectorError::Resolver(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ssl")]
|
|
||||||
impl From<SslError> for ConnectorError {
|
|
||||||
fn from(err: SslError) -> ConnectorError {
|
|
||||||
ConnectorError::SslError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
impl<T> From<HandshakeError<T>> for ConnectorError {
|
impl<T> From<HandshakeError<T>> for ConnectorError {
|
||||||
fn from(err: HandshakeError<T>) -> ConnectorError {
|
fn from(err: HandshakeError<T>) -> ConnectorError {
|
||||||
@ -90,10 +71,10 @@ impl<T> From<HandshakeError<T>> for ConnectorError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A set of errors that can occur during request sending and response reading
|
/// A set of errors that can occur during request sending and response reading
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum SendRequestError {
|
pub enum SendRequestError {
|
||||||
/// Failed to connect to host
|
/// Failed to connect to host
|
||||||
// #[fail(display = "Failed to connect to host: {}", _0)]
|
#[display(fmt = "Failed to connect to host: {}", _0)]
|
||||||
Connector(ConnectorError),
|
Connector(ConnectorError),
|
||||||
/// Error sending request
|
/// Error sending request
|
||||||
Send(io::Error),
|
Send(io::Error),
|
||||||
@ -102,27 +83,3 @@ pub enum SendRequestError {
|
|||||||
/// Error sending request body
|
/// Error sending request body
|
||||||
Body(Error),
|
Body(Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for SendRequestError {
|
|
||||||
fn from(err: io::Error) -> SendRequestError {
|
|
||||||
SendRequestError::Send(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ConnectorError> for SendRequestError {
|
|
||||||
fn from(err: ConnectorError) -> SendRequestError {
|
|
||||||
SendRequestError::Connector(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ParseError> for SendRequestError {
|
|
||||||
fn from(err: ParseError) -> SendRequestError {
|
|
||||||
SendRequestError::Response(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Error> for SendRequestError {
|
|
||||||
fn from(err: Error) -> SendRequestError {
|
|
||||||
SendRequestError::Body(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
401
src/error.rs
401
src/error.rs
@ -1,13 +1,14 @@
|
|||||||
//! Error and Result module
|
//! Error and Result module
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use std::sync::Mutex;
|
|
||||||
use std::{fmt, io, result};
|
use std::{fmt, io, result};
|
||||||
|
|
||||||
// use actix::MailboxError;
|
// use actix::MailboxError;
|
||||||
|
use backtrace::Backtrace;
|
||||||
use cookie;
|
use cookie;
|
||||||
use failure::{self, Backtrace, Fail};
|
use derive_more::{Display, From};
|
||||||
use futures::Canceled;
|
use futures::Canceled;
|
||||||
use http::uri::InvalidUri;
|
use http::uri::InvalidUri;
|
||||||
use http::{header, Error as HttpError, StatusCode};
|
use http::{header, Error as HttpError, StatusCode};
|
||||||
@ -21,7 +22,7 @@ use tokio_timer::Error as TimerError;
|
|||||||
pub use cookie::ParseError as CookieParseError;
|
pub use cookie::ParseError as CookieParseError;
|
||||||
|
|
||||||
use crate::body::Body;
|
use crate::body::Body;
|
||||||
use crate::response::{Response, ResponseParts};
|
use crate::response::Response;
|
||||||
|
|
||||||
/// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
|
/// A specialized [`Result`](https://doc.rust-lang.org/std/result/enum.Result.html)
|
||||||
/// for actix web operations
|
/// for actix web operations
|
||||||
@ -47,20 +48,6 @@ pub struct Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
/// Deprecated way to reference the underlying response error.
|
|
||||||
#[deprecated(
|
|
||||||
since = "0.6.0",
|
|
||||||
note = "please use `Error::as_response_error()` instead"
|
|
||||||
)]
|
|
||||||
pub fn cause(&self) -> &ResponseError {
|
|
||||||
self.cause.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a reference to the underlying cause of this `Error` as `Fail`
|
|
||||||
pub fn as_fail(&self) -> &Fail {
|
|
||||||
self.cause.as_fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the reference to the underlying `ResponseError`.
|
/// Returns the reference to the underlying `ResponseError`.
|
||||||
pub fn as_response_error(&self) -> &ResponseError {
|
pub fn as_response_error(&self) -> &ResponseError {
|
||||||
self.cause.as_ref()
|
self.cause.as_ref()
|
||||||
@ -78,27 +65,27 @@ impl Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to downcast this `Error` to a particular `Fail` type by
|
// /// Attempts to downcast this `Error` to a particular `Fail` type by
|
||||||
/// reference.
|
// /// reference.
|
||||||
///
|
// ///
|
||||||
/// If the underlying error is not of type `T`, this will return `None`.
|
// /// If the underlying error is not of type `T`, this will return `None`.
|
||||||
pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
|
// pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
|
||||||
// in the most trivial way the cause is directly of the requested type.
|
// // in the most trivial way the cause is directly of the requested type.
|
||||||
if let Some(rv) = Fail::downcast_ref(self.cause.as_fail()) {
|
// if let Some(rv) = Fail::downcast_ref(self.cause.as_fail()) {
|
||||||
return Some(rv);
|
// return Some(rv);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// in the more complex case the error has been constructed from a failure
|
// // in the more complex case the error has been constructed from a failure
|
||||||
// error. This happens because we implement From<failure::Error> by
|
// // error. This happens because we implement From<failure::Error> by
|
||||||
// calling compat() and then storing it here. In failure this is
|
// // calling compat() and then storing it here. In failure this is
|
||||||
// represented by a failure::Error being wrapped in a failure::Compat.
|
// // represented by a failure::Error being wrapped in a failure::Compat.
|
||||||
//
|
// //
|
||||||
// So we first downcast into that compat, to then further downcast through
|
// // So we first downcast into that compat, to then further downcast through
|
||||||
// the failure's Error downcasting system into the original failure.
|
// // the failure's Error downcasting system into the original failure.
|
||||||
let compat: Option<&failure::Compat<failure::Error>> =
|
// let compat: Option<&failure::Compat<failure::Error>> =
|
||||||
Fail::downcast_ref(self.cause.as_fail());
|
// Fail::downcast_ref(self.cause.as_fail());
|
||||||
compat.and_then(|e| e.get_ref().downcast_ref())
|
// compat.and_then(|e| e.get_ref().downcast_ref())
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Converts error to a response instance and set error message as response body
|
/// Converts error to a response instance and set error message as response body
|
||||||
pub fn response_with_message(self) -> Response {
|
pub fn response_with_message(self) -> Response {
|
||||||
@ -108,36 +95,41 @@ impl Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper trait to downcast a response error into a fail.
|
// /// Helper trait to downcast a response error into a fail.
|
||||||
///
|
// ///
|
||||||
/// This is currently not exposed because it's unclear if this is the best way
|
// /// This is currently not exposed because it's unclear if this is the best way
|
||||||
/// to achieve the downcasting on `Error` for which this is needed.
|
// /// to achieve the downcasting on `Error` for which this is needed.
|
||||||
#[doc(hidden)]
|
// #[doc(hidden)]
|
||||||
pub trait InternalResponseErrorAsFail {
|
// pub trait InternalResponseErrorAsFail {
|
||||||
#[doc(hidden)]
|
// #[doc(hidden)]
|
||||||
fn as_fail(&self) -> &Fail;
|
// fn as_fail(&self) -> &Fail;
|
||||||
#[doc(hidden)]
|
// #[doc(hidden)]
|
||||||
fn as_mut_fail(&mut self) -> &mut Fail;
|
// fn as_mut_fail(&mut self) -> &mut Fail;
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[doc(hidden)]
|
// #[doc(hidden)]
|
||||||
impl<T: ResponseError> InternalResponseErrorAsFail for T {
|
// impl<T: ResponseError> InternalResponseErrorAsFail for T {
|
||||||
fn as_fail(&self) -> &Fail {
|
// fn as_fail(&self) -> &Fail {
|
||||||
self
|
// self
|
||||||
}
|
// }
|
||||||
fn as_mut_fail(&mut self) -> &mut Fail {
|
// fn as_mut_fail(&mut self) -> &mut Fail {
|
||||||
self
|
// self
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Error that can be converted to `Response`
|
/// Error that can be converted to `Response`
|
||||||
pub trait ResponseError: Fail + InternalResponseErrorAsFail {
|
pub trait ResponseError: fmt::Debug + fmt::Display {
|
||||||
/// Create response for error
|
/// Create response for error
|
||||||
///
|
///
|
||||||
/// Internal server error is generated by default.
|
/// Internal server error is generated by default.
|
||||||
fn error_response(&self) -> Response {
|
fn error_response(&self) -> Response {
|
||||||
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Response
|
||||||
|
fn backtrace(&self) -> Option<&Backtrace> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@ -169,7 +161,7 @@ impl From<Error> for Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// `Error` for any error that implements `ResponseError`
|
/// `Error` for any error that implements `ResponseError`
|
||||||
impl<T: ResponseError> From<T> for Error {
|
impl<T: ResponseError + 'static> From<T> for Error {
|
||||||
fn from(err: T) -> Error {
|
fn from(err: T) -> Error {
|
||||||
let backtrace = if err.backtrace().is_none() {
|
let backtrace = if err.backtrace().is_none() {
|
||||||
Some(Backtrace::new())
|
Some(Backtrace::new())
|
||||||
@ -183,17 +175,17 @@ impl<T: ResponseError> From<T> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compatibility for `failure::Error`
|
// /// Compatibility for `failure::Error`
|
||||||
impl<T> ResponseError for failure::Compat<T> where
|
// impl<T> ResponseError for failure::Compat<T> where
|
||||||
T: fmt::Display + fmt::Debug + Sync + Send + 'static
|
// T: fmt::Display + fmt::Debug + Sync + Send + 'static
|
||||||
{
|
// {
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl From<failure::Error> for Error {
|
// impl From<failure::Error> for Error {
|
||||||
fn from(err: failure::Error) -> Error {
|
// fn from(err: failure::Error) -> Error {
|
||||||
err.compat().into()
|
// err.compat().into()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// `InternalServerError` for `JsonError`
|
/// `InternalServerError` for `JsonError`
|
||||||
impl ResponseError for JsonError {}
|
impl ResponseError for JsonError {}
|
||||||
@ -254,40 +246,40 @@ impl ResponseError for Canceled {}
|
|||||||
// impl ResponseError for MailboxError {}
|
// impl ResponseError for MailboxError {}
|
||||||
|
|
||||||
/// A set of errors that can occur during parsing HTTP streams
|
/// A set of errors that can occur during parsing HTTP streams
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display)]
|
||||||
pub enum ParseError {
|
pub enum ParseError {
|
||||||
/// An invalid `Method`, such as `GE.T`.
|
/// An invalid `Method`, such as `GE.T`.
|
||||||
#[fail(display = "Invalid Method specified")]
|
#[display(fmt = "Invalid Method specified")]
|
||||||
Method,
|
Method,
|
||||||
/// An invalid `Uri`, such as `exam ple.domain`.
|
/// An invalid `Uri`, such as `exam ple.domain`.
|
||||||
#[fail(display = "Uri error: {}", _0)]
|
#[display(fmt = "Uri error: {}", _0)]
|
||||||
Uri(InvalidUri),
|
Uri(InvalidUri),
|
||||||
/// An invalid `HttpVersion`, such as `HTP/1.1`
|
/// An invalid `HttpVersion`, such as `HTP/1.1`
|
||||||
#[fail(display = "Invalid HTTP version specified")]
|
#[display(fmt = "Invalid HTTP version specified")]
|
||||||
Version,
|
Version,
|
||||||
/// An invalid `Header`.
|
/// An invalid `Header`.
|
||||||
#[fail(display = "Invalid Header provided")]
|
#[display(fmt = "Invalid Header provided")]
|
||||||
Header,
|
Header,
|
||||||
/// A message head is too large to be reasonable.
|
/// A message head is too large to be reasonable.
|
||||||
#[fail(display = "Message head is too large")]
|
#[display(fmt = "Message head is too large")]
|
||||||
TooLarge,
|
TooLarge,
|
||||||
/// A message reached EOF, but is not complete.
|
/// A message reached EOF, but is not complete.
|
||||||
#[fail(display = "Message is incomplete")]
|
#[display(fmt = "Message is incomplete")]
|
||||||
Incomplete,
|
Incomplete,
|
||||||
/// An invalid `Status`, such as `1337 ELITE`.
|
/// An invalid `Status`, such as `1337 ELITE`.
|
||||||
#[fail(display = "Invalid Status provided")]
|
#[display(fmt = "Invalid Status provided")]
|
||||||
Status,
|
Status,
|
||||||
/// A timeout occurred waiting for an IO event.
|
/// A timeout occurred waiting for an IO event.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[fail(display = "Timeout")]
|
#[display(fmt = "Timeout")]
|
||||||
Timeout,
|
Timeout,
|
||||||
/// An `io::Error` that occurred while trying to read or write to a network
|
/// An `io::Error` that occurred while trying to read or write to a network
|
||||||
/// stream.
|
/// stream.
|
||||||
#[fail(display = "IO error: {}", _0)]
|
#[display(fmt = "IO error: {}", _0)]
|
||||||
Io(#[cause] IoError),
|
Io(IoError),
|
||||||
/// Parsing a field as string failed
|
/// Parsing a field as string failed
|
||||||
#[fail(display = "UTF8 error: {}", _0)]
|
#[display(fmt = "UTF8 error: {}", _0)]
|
||||||
Utf8(#[cause] Utf8Error),
|
Utf8(Utf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `BadRequest` for `ParseError`
|
/// Return `BadRequest` for `ParseError`
|
||||||
@ -335,20 +327,20 @@ impl From<httparse::Error> for ParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Display, Debug)]
|
||||||
/// A set of errors that can occur during payload parsing
|
/// A set of errors that can occur during payload parsing
|
||||||
pub enum PayloadError {
|
pub enum PayloadError {
|
||||||
/// A payload reached EOF, but is not complete.
|
/// A payload reached EOF, but is not complete.
|
||||||
#[fail(display = "A payload reached EOF, but is not complete.")]
|
#[display(fmt = "A payload reached EOF, but is not complete.")]
|
||||||
Incomplete(Option<io::Error>),
|
Incomplete(Option<io::Error>),
|
||||||
/// Content encoding stream corruption
|
/// Content encoding stream corruption
|
||||||
#[fail(display = "Can not decode content-encoding.")]
|
#[display(fmt = "Can not decode content-encoding.")]
|
||||||
EncodingCorrupted,
|
EncodingCorrupted,
|
||||||
/// A payload reached size limit.
|
/// A payload reached size limit.
|
||||||
#[fail(display = "A payload reached size limit.")]
|
#[display(fmt = "A payload reached size limit.")]
|
||||||
Overflow,
|
Overflow,
|
||||||
/// A payload length is unknown.
|
/// A payload length is unknown.
|
||||||
#[fail(display = "A payload length is unknown.")]
|
#[display(fmt = "A payload length is unknown.")]
|
||||||
UnknownLength,
|
UnknownLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,44 +370,44 @@ impl ResponseError for cookie::ParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Display)]
|
||||||
/// A set of errors that can occur during dispatching http requests
|
/// A set of errors that can occur during dispatching http requests
|
||||||
pub enum DispatchError<E: fmt::Debug> {
|
pub enum DispatchError<E: fmt::Debug> {
|
||||||
/// Service error
|
/// Service error
|
||||||
// #[fail(display = "Application specific error: {}", _0)]
|
#[display(fmt = "Service specific error: {:?}", _0)]
|
||||||
Service(E),
|
Service(E),
|
||||||
|
|
||||||
/// An `io::Error` that occurred while trying to read or write to a network
|
/// An `io::Error` that occurred while trying to read or write to a network
|
||||||
/// stream.
|
/// stream.
|
||||||
// #[fail(display = "IO error: {}", _0)]
|
#[display(fmt = "IO error: {}", _0)]
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
|
|
||||||
/// Http request parse error.
|
/// Http request parse error.
|
||||||
// #[fail(display = "Parse error: {}", _0)]
|
#[display(fmt = "Parse error: {}", _0)]
|
||||||
Parse(ParseError),
|
Parse(ParseError),
|
||||||
|
|
||||||
/// The first request did not complete within the specified timeout.
|
/// The first request did not complete within the specified timeout.
|
||||||
// #[fail(display = "The first request did not complete within the specified timeout")]
|
#[display(fmt = "The first request did not complete within the specified timeout")]
|
||||||
SlowRequestTimeout,
|
SlowRequestTimeout,
|
||||||
|
|
||||||
/// Disconnect timeout. Makes sense for ssl streams.
|
/// Disconnect timeout. Makes sense for ssl streams.
|
||||||
// #[fail(display = "Connection shutdown timeout")]
|
#[display(fmt = "Connection shutdown timeout")]
|
||||||
DisconnectTimeout,
|
DisconnectTimeout,
|
||||||
|
|
||||||
/// Payload is not consumed
|
/// Payload is not consumed
|
||||||
// #[fail(display = "Task is completed but request's payload is not consumed")]
|
#[display(fmt = "Task is completed but request's payload is not consumed")]
|
||||||
PayloadIsNotConsumed,
|
PayloadIsNotConsumed,
|
||||||
|
|
||||||
/// Malformed request
|
/// Malformed request
|
||||||
// #[fail(display = "Malformed request")]
|
#[display(fmt = "Malformed request")]
|
||||||
MalformedRequest,
|
MalformedRequest,
|
||||||
|
|
||||||
/// Internal error
|
/// Internal error
|
||||||
// #[fail(display = "Internal error")]
|
#[display(fmt = "Internal error")]
|
||||||
InternalError,
|
InternalError,
|
||||||
|
|
||||||
/// Unknown error
|
/// Unknown error
|
||||||
// #[fail(display = "Unknown error")]
|
#[display(fmt = "Unknown error")]
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,13 +424,13 @@ impl<E: fmt::Debug> From<io::Error> for DispatchError<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A set of error that can occure during parsing content type
|
/// A set of error that can occure during parsing content type
|
||||||
#[derive(Fail, PartialEq, Debug)]
|
#[derive(PartialEq, Debug, Display)]
|
||||||
pub enum ContentTypeError {
|
pub enum ContentTypeError {
|
||||||
/// Can not parse content type
|
/// Can not parse content type
|
||||||
#[fail(display = "Can not parse content type")]
|
#[display(fmt = "Can not parse content type")]
|
||||||
ParseError,
|
ParseError,
|
||||||
/// Unknown content encoding
|
/// Unknown content encoding
|
||||||
#[fail(display = "Unknown content encoding")]
|
#[display(fmt = "Unknown content encoding")]
|
||||||
UnknownEncoding,
|
UnknownEncoding,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,28 +442,26 @@ impl ResponseError for ContentTypeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A set of errors that can occur during parsing urlencoded payloads
|
/// A set of errors that can occur during parsing urlencoded payloads
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum UrlencodedError {
|
pub enum UrlencodedError {
|
||||||
/// Can not decode chunked transfer encoding
|
/// Can not decode chunked transfer encoding
|
||||||
#[fail(display = "Can not decode chunked transfer encoding")]
|
#[display(fmt = "Can not decode chunked transfer encoding")]
|
||||||
Chunked,
|
Chunked,
|
||||||
/// Payload size is bigger than allowed. (default: 256kB)
|
/// Payload size is bigger than allowed. (default: 256kB)
|
||||||
#[fail(
|
#[display(fmt = "Urlencoded payload size is bigger than allowed. (default: 256kB)")]
|
||||||
display = "Urlencoded payload size is bigger than allowed. (default: 256kB)"
|
|
||||||
)]
|
|
||||||
Overflow,
|
Overflow,
|
||||||
/// Payload size is now known
|
/// Payload size is now known
|
||||||
#[fail(display = "Payload size is now known")]
|
#[display(fmt = "Payload size is now known")]
|
||||||
UnknownLength,
|
UnknownLength,
|
||||||
/// Content type error
|
/// Content type error
|
||||||
#[fail(display = "Content type error")]
|
#[display(fmt = "Content type error")]
|
||||||
ContentType,
|
ContentType,
|
||||||
/// Parse error
|
/// Parse error
|
||||||
#[fail(display = "Parse error")]
|
#[display(fmt = "Parse error")]
|
||||||
Parse,
|
Parse,
|
||||||
/// Payload error
|
/// Payload error
|
||||||
#[fail(display = "Error that occur during reading payload: {}", _0)]
|
#[display(fmt = "Error that occur during reading payload: {}", _0)]
|
||||||
Payload(#[cause] PayloadError),
|
Payload(PayloadError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `BadRequest` for `UrlencodedError`
|
/// Return `BadRequest` for `UrlencodedError`
|
||||||
@ -485,27 +475,21 @@ impl ResponseError for UrlencodedError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PayloadError> for UrlencodedError {
|
|
||||||
fn from(err: PayloadError) -> UrlencodedError {
|
|
||||||
UrlencodedError::Payload(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A set of errors that can occur during parsing json payloads
|
/// A set of errors that can occur during parsing json payloads
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum JsonPayloadError {
|
pub enum JsonPayloadError {
|
||||||
/// Payload size is bigger than allowed. (default: 256kB)
|
/// Payload size is bigger than allowed. (default: 256kB)
|
||||||
#[fail(display = "Json payload size is bigger than allowed. (default: 256kB)")]
|
#[display(fmt = "Json payload size is bigger than allowed. (default: 256kB)")]
|
||||||
Overflow,
|
Overflow,
|
||||||
/// Content type error
|
/// Content type error
|
||||||
#[fail(display = "Content type error")]
|
#[display(fmt = "Content type error")]
|
||||||
ContentType,
|
ContentType,
|
||||||
/// Deserialize error
|
/// Deserialize error
|
||||||
#[fail(display = "Json deserialize error: {}", _0)]
|
#[display(fmt = "Json deserialize error: {}", _0)]
|
||||||
Deserialize(#[cause] JsonError),
|
Deserialize(JsonError),
|
||||||
/// Payload error
|
/// Payload error
|
||||||
#[fail(display = "Error that occur during reading payload: {}", _0)]
|
#[display(fmt = "Error that occur during reading payload: {}", _0)]
|
||||||
Payload(#[cause] PayloadError),
|
Payload(PayloadError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return `BadRequest` for `UrlencodedError`
|
/// Return `BadRequest` for `UrlencodedError`
|
||||||
@ -518,19 +502,8 @@ impl ResponseError for JsonPayloadError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PayloadError> for JsonPayloadError {
|
|
||||||
fn from(err: PayloadError) -> JsonPayloadError {
|
|
||||||
JsonPayloadError::Payload(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<JsonError> for JsonPayloadError {
|
|
||||||
fn from(err: JsonError) -> JsonPayloadError {
|
|
||||||
JsonPayloadError::Deserialize(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error type returned when reading body as lines.
|
/// Error type returned when reading body as lines.
|
||||||
|
#[derive(From)]
|
||||||
pub enum ReadlinesError {
|
pub enum ReadlinesError {
|
||||||
/// Error when decoding a line.
|
/// Error when decoding a line.
|
||||||
EncodingError,
|
EncodingError,
|
||||||
@ -542,18 +515,6 @@ pub enum ReadlinesError {
|
|||||||
ContentTypeError(ContentTypeError),
|
ContentTypeError(ContentTypeError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PayloadError> for ReadlinesError {
|
|
||||||
fn from(err: PayloadError) -> Self {
|
|
||||||
ReadlinesError::PayloadError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ContentTypeError> for ReadlinesError {
|
|
||||||
fn from(err: ContentTypeError) -> Self {
|
|
||||||
ReadlinesError::ContentTypeError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper type that can wrap any error and generate custom response.
|
/// Helper type that can wrap any error and generate custom response.
|
||||||
///
|
///
|
||||||
/// In following example any `io::Error` will be converted into "BAD REQUEST"
|
/// In following example any `io::Error` will be converted into "BAD REQUEST"
|
||||||
@ -578,7 +539,7 @@ pub struct InternalError<T> {
|
|||||||
|
|
||||||
enum InternalErrorType {
|
enum InternalErrorType {
|
||||||
Status(StatusCode),
|
Status(StatusCode),
|
||||||
Response(Box<Mutex<Option<ResponseParts>>>),
|
Response(RefCell<Option<Response>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> InternalError<T> {
|
impl<T> InternalError<T> {
|
||||||
@ -593,27 +554,17 @@ impl<T> InternalError<T> {
|
|||||||
|
|
||||||
/// Create `InternalError` with predefined `Response`.
|
/// Create `InternalError` with predefined `Response`.
|
||||||
pub fn from_response(cause: T, response: Response) -> Self {
|
pub fn from_response(cause: T, response: Response) -> Self {
|
||||||
let resp = response.into_parts();
|
|
||||||
InternalError {
|
InternalError {
|
||||||
cause,
|
cause,
|
||||||
status: InternalErrorType::Response(Box::new(Mutex::new(Some(resp)))),
|
status: InternalErrorType::Response(RefCell::new(Some(response))),
|
||||||
backtrace: Backtrace::new(),
|
backtrace: Backtrace::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Fail for InternalError<T>
|
|
||||||
where
|
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
|
||||||
{
|
|
||||||
fn backtrace(&self) -> Option<&Backtrace> {
|
|
||||||
Some(&self.backtrace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for InternalError<T>
|
impl<T> fmt::Debug for InternalError<T>
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + 'static,
|
T: fmt::Debug + 'static,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.cause, f)
|
fmt::Debug::fmt(&self.cause, f)
|
||||||
@ -622,7 +573,7 @@ where
|
|||||||
|
|
||||||
impl<T> fmt::Display for InternalError<T>
|
impl<T> fmt::Display for InternalError<T>
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Display + 'static,
|
T: fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Display::fmt(&self.cause, f)
|
fmt::Display::fmt(&self.cause, f)
|
||||||
@ -631,14 +582,18 @@ where
|
|||||||
|
|
||||||
impl<T> ResponseError for InternalError<T>
|
impl<T> ResponseError for InternalError<T>
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
|
fn backtrace(&self) -> Option<&Backtrace> {
|
||||||
|
Some(&self.backtrace)
|
||||||
|
}
|
||||||
|
|
||||||
fn error_response(&self) -> Response {
|
fn error_response(&self) -> Response {
|
||||||
match self.status {
|
match self.status {
|
||||||
InternalErrorType::Status(st) => Response::new(st),
|
InternalErrorType::Status(st) => Response::new(st),
|
||||||
InternalErrorType::Response(ref resp) => {
|
InternalErrorType::Response(ref resp) => {
|
||||||
if let Some(resp) = resp.lock().unwrap().take() {
|
if let Some(resp) = resp.borrow_mut().take() {
|
||||||
Response::<()>::from_parts(resp)
|
resp
|
||||||
} else {
|
} else {
|
||||||
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
}
|
}
|
||||||
@ -659,7 +614,7 @@ impl From<Response> for Error {
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorBadRequest<T>(err: T) -> Error
|
pub fn ErrorBadRequest<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::BAD_REQUEST).into()
|
InternalError::new(err, StatusCode::BAD_REQUEST).into()
|
||||||
}
|
}
|
||||||
@ -669,7 +624,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorUnauthorized<T>(err: T) -> Error
|
pub fn ErrorUnauthorized<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::UNAUTHORIZED).into()
|
InternalError::new(err, StatusCode::UNAUTHORIZED).into()
|
||||||
}
|
}
|
||||||
@ -679,7 +634,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorForbidden<T>(err: T) -> Error
|
pub fn ErrorForbidden<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::FORBIDDEN).into()
|
InternalError::new(err, StatusCode::FORBIDDEN).into()
|
||||||
}
|
}
|
||||||
@ -689,7 +644,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorNotFound<T>(err: T) -> Error
|
pub fn ErrorNotFound<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::NOT_FOUND).into()
|
InternalError::new(err, StatusCode::NOT_FOUND).into()
|
||||||
}
|
}
|
||||||
@ -699,7 +654,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorMethodNotAllowed<T>(err: T) -> Error
|
pub fn ErrorMethodNotAllowed<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::METHOD_NOT_ALLOWED).into()
|
InternalError::new(err, StatusCode::METHOD_NOT_ALLOWED).into()
|
||||||
}
|
}
|
||||||
@ -709,7 +664,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorRequestTimeout<T>(err: T) -> Error
|
pub fn ErrorRequestTimeout<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::REQUEST_TIMEOUT).into()
|
InternalError::new(err, StatusCode::REQUEST_TIMEOUT).into()
|
||||||
}
|
}
|
||||||
@ -719,7 +674,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorConflict<T>(err: T) -> Error
|
pub fn ErrorConflict<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::CONFLICT).into()
|
InternalError::new(err, StatusCode::CONFLICT).into()
|
||||||
}
|
}
|
||||||
@ -729,7 +684,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorGone<T>(err: T) -> Error
|
pub fn ErrorGone<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::GONE).into()
|
InternalError::new(err, StatusCode::GONE).into()
|
||||||
}
|
}
|
||||||
@ -739,7 +694,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorPreconditionFailed<T>(err: T) -> Error
|
pub fn ErrorPreconditionFailed<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::PRECONDITION_FAILED).into()
|
InternalError::new(err, StatusCode::PRECONDITION_FAILED).into()
|
||||||
}
|
}
|
||||||
@ -749,7 +704,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorExpectationFailed<T>(err: T) -> Error
|
pub fn ErrorExpectationFailed<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::EXPECTATION_FAILED).into()
|
InternalError::new(err, StatusCode::EXPECTATION_FAILED).into()
|
||||||
}
|
}
|
||||||
@ -759,7 +714,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorInternalServerError<T>(err: T) -> Error
|
pub fn ErrorInternalServerError<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR).into()
|
InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR).into()
|
||||||
}
|
}
|
||||||
@ -769,7 +724,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorNotImplemented<T>(err: T) -> Error
|
pub fn ErrorNotImplemented<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::NOT_IMPLEMENTED).into()
|
InternalError::new(err, StatusCode::NOT_IMPLEMENTED).into()
|
||||||
}
|
}
|
||||||
@ -779,7 +734,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorBadGateway<T>(err: T) -> Error
|
pub fn ErrorBadGateway<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::BAD_GATEWAY).into()
|
InternalError::new(err, StatusCode::BAD_GATEWAY).into()
|
||||||
}
|
}
|
||||||
@ -789,7 +744,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorServiceUnavailable<T>(err: T) -> Error
|
pub fn ErrorServiceUnavailable<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::SERVICE_UNAVAILABLE).into()
|
InternalError::new(err, StatusCode::SERVICE_UNAVAILABLE).into()
|
||||||
}
|
}
|
||||||
@ -799,7 +754,7 @@ where
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn ErrorGatewayTimeout<T>(err: T) -> Error
|
pub fn ErrorGatewayTimeout<T>(err: T) -> Error
|
||||||
where
|
where
|
||||||
T: Send + Sync + fmt::Debug + fmt::Display + 'static,
|
T: fmt::Debug + fmt::Display + 'static,
|
||||||
{
|
{
|
||||||
InternalError::new(err, StatusCode::GATEWAY_TIMEOUT).into()
|
InternalError::new(err, StatusCode::GATEWAY_TIMEOUT).into()
|
||||||
}
|
}
|
||||||
@ -808,10 +763,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use cookie::ParseError as CookieParseError;
|
use cookie::ParseError as CookieParseError;
|
||||||
use failure;
|
|
||||||
use http::{Error as HttpError, StatusCode};
|
use http::{Error as HttpError, StatusCode};
|
||||||
use httparse;
|
use httparse;
|
||||||
use std::env;
|
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
@ -829,11 +782,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_as_fail() {
|
fn test_as_response() {
|
||||||
let orig = io::Error::new(io::ErrorKind::Other, "other");
|
let orig = io::Error::new(io::ErrorKind::Other, "other");
|
||||||
let desc = orig.description().to_owned();
|
let e: Error = ParseError::Io(orig).into();
|
||||||
let e = ParseError::Io(orig);
|
assert_eq!(format!("{}", e.as_response_error()), "IO error: other");
|
||||||
assert_eq!(format!("{}", e.cause().unwrap()), desc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -847,7 +799,7 @@ mod tests {
|
|||||||
let orig = io::Error::new(io::ErrorKind::Other, "other");
|
let orig = io::Error::new(io::ErrorKind::Other, "other");
|
||||||
let desc = orig.description().to_owned();
|
let desc = orig.description().to_owned();
|
||||||
let e = Error::from(orig);
|
let e = Error::from(orig);
|
||||||
assert_eq!(format!("{}", e.as_fail()), desc);
|
assert_eq!(format!("{}", e.as_response_error()), desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -881,7 +833,7 @@ mod tests {
|
|||||||
($from:expr => $error:pat) => {
|
($from:expr => $error:pat) => {
|
||||||
match ParseError::from($from) {
|
match ParseError::from($from) {
|
||||||
e @ $error => {
|
e @ $error => {
|
||||||
let desc = format!("{}", e.cause().unwrap());
|
let desc = format!("{}", e);
|
||||||
assert_eq!(desc, $from.description().to_owned());
|
assert_eq!(desc, $from.description().to_owned());
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:?}", $from),
|
_ => unreachable!("{:?}", $from),
|
||||||
@ -891,8 +843,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from() {
|
fn test_from() {
|
||||||
from_and_cause!(io::Error::new(io::ErrorKind::Other, "other") => ParseError::Io(..));
|
// from_and_cause!(io::Error::new(io::ErrorKind::Other, "other") => ParseError::Io(..));
|
||||||
|
|
||||||
from!(httparse::Error::HeaderName => ParseError::Header);
|
from!(httparse::Error::HeaderName => ParseError::Header);
|
||||||
from!(httparse::Error::HeaderName => ParseError::Header);
|
from!(httparse::Error::HeaderName => ParseError::Header);
|
||||||
from!(httparse::Error::HeaderValue => ParseError::Header);
|
from!(httparse::Error::HeaderValue => ParseError::Header);
|
||||||
@ -903,22 +854,22 @@ mod tests {
|
|||||||
from!(httparse::Error::Version => ParseError::Version);
|
from!(httparse::Error::Version => ParseError::Version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn failure_error() {
|
// fn failure_error() {
|
||||||
const NAME: &str = "RUST_BACKTRACE";
|
// const NAME: &str = "RUST_BACKTRACE";
|
||||||
let old_tb = env::var(NAME);
|
// let old_tb = env::var(NAME);
|
||||||
env::set_var(NAME, "0");
|
// env::set_var(NAME, "0");
|
||||||
let error = failure::err_msg("Hello!");
|
// let error = failure::err_msg("Hello!");
|
||||||
let resp: Error = error.into();
|
// let resp: Error = error.into();
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
format!("{:?}", resp),
|
// format!("{:?}", resp),
|
||||||
"Compat { error: ErrorMessage { msg: \"Hello!\" } }\n\n"
|
// "Compat { error: ErrorMessage { msg: \"Hello!\" } }\n\n"
|
||||||
);
|
// );
|
||||||
match old_tb {
|
// match old_tb {
|
||||||
Ok(x) => env::set_var(NAME, x),
|
// Ok(x) => env::set_var(NAME, x),
|
||||||
_ => env::remove_var(NAME),
|
// _ => env::remove_var(NAME),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_internal_error() {
|
fn test_internal_error() {
|
||||||
@ -928,31 +879,31 @@ mod tests {
|
|||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_error_downcasting_direct() {
|
// fn test_error_downcasting_direct() {
|
||||||
#[derive(Debug, Fail)]
|
// #[derive(Debug, Display)]
|
||||||
#[fail(display = "demo error")]
|
// #[display(fmt = "demo error")]
|
||||||
struct DemoError;
|
// struct DemoError;
|
||||||
|
|
||||||
impl ResponseError for DemoError {}
|
// impl ResponseError for DemoError {}
|
||||||
|
|
||||||
let err: Error = DemoError.into();
|
// let err: Error = DemoError.into();
|
||||||
let err_ref: &DemoError = err.downcast_ref().unwrap();
|
// let err_ref: &DemoError = err.downcast_ref().unwrap();
|
||||||
assert_eq!(err_ref.to_string(), "demo error");
|
// assert_eq!(err_ref.to_string(), "demo error");
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_error_downcasting_compat() {
|
// fn test_error_downcasting_compat() {
|
||||||
#[derive(Debug, Fail)]
|
// #[derive(Debug, Display)]
|
||||||
#[fail(display = "demo error")]
|
// #[display(fmt = "demo error")]
|
||||||
struct DemoError;
|
// struct DemoError;
|
||||||
|
|
||||||
impl ResponseError for DemoError {}
|
// impl ResponseError for DemoError {}
|
||||||
|
|
||||||
let err: Error = failure::Error::from(DemoError).into();
|
// let err: Error = failure::Error::from(DemoError).into();
|
||||||
let err_ref: &DemoError = err.downcast_ref().unwrap();
|
// let err_ref: &DemoError = err.downcast_ref().unwrap();
|
||||||
assert_eq!(err_ref.to_string(), "demo error");
|
// assert_eq!(err_ref.to_string(), "demo error");
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_error_helpers() {
|
fn test_error_helpers() {
|
||||||
|
@ -240,17 +240,6 @@ impl<B: MessageBody> Response<B> {
|
|||||||
pub(crate) fn release(self) {
|
pub(crate) fn release(self) {
|
||||||
ResponsePool::release(self.0);
|
ResponsePool::release(self.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_parts(self) -> ResponseParts {
|
|
||||||
self.0.into_parts()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn from_parts(parts: ResponseParts) -> Response {
|
|
||||||
Response(
|
|
||||||
Box::new(InnerResponse::from_parts(parts)),
|
|
||||||
ResponseBody::Body(Body::Empty),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: MessageBody> fmt::Debug for Response<B> {
|
impl<B: MessageBody> fmt::Debug for Response<B> {
|
||||||
@ -736,11 +725,6 @@ struct InnerResponse {
|
|||||||
pool: &'static ResponsePool,
|
pool: &'static ResponsePool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct ResponseParts {
|
|
||||||
head: ResponseHead,
|
|
||||||
error: Option<Error>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InnerResponse {
|
impl InnerResponse {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new(status: StatusCode, pool: &'static ResponsePool) -> InnerResponse {
|
fn new(status: StatusCode, pool: &'static ResponsePool) -> InnerResponse {
|
||||||
@ -757,23 +741,6 @@ impl InnerResponse {
|
|||||||
error: None,
|
error: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is for failure, we can not have Send + Sync on Streaming and Actor response
|
|
||||||
fn into_parts(self) -> ResponseParts {
|
|
||||||
ResponseParts {
|
|
||||||
head: self.head,
|
|
||||||
error: self.error,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_parts(parts: ResponseParts) -> InnerResponse {
|
|
||||||
InnerResponse {
|
|
||||||
head: parts.head,
|
|
||||||
response_size: 0,
|
|
||||||
error: parts.error,
|
|
||||||
pool: ResponsePool::pool(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal use only!
|
/// Internal use only!
|
||||||
|
@ -2,82 +2,52 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use actix_connector::ConnectorError;
|
use actix_connector::ConnectorError;
|
||||||
use failure::Fail;
|
use derive_more::{Display, From};
|
||||||
use http::{header::HeaderValue, Error as HttpError, StatusCode};
|
use http::{header::HeaderValue, Error as HttpError, StatusCode};
|
||||||
|
|
||||||
use crate::error::ParseError;
|
use crate::error::ParseError;
|
||||||
use crate::ws::ProtocolError;
|
use crate::ws::ProtocolError;
|
||||||
|
|
||||||
/// Websocket client error
|
/// Websocket client error
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum ClientError {
|
pub enum ClientError {
|
||||||
/// Invalid url
|
/// Invalid url
|
||||||
#[fail(display = "Invalid url")]
|
#[display(fmt = "Invalid url")]
|
||||||
InvalidUrl,
|
InvalidUrl,
|
||||||
/// Invalid response status
|
/// Invalid response status
|
||||||
#[fail(display = "Invalid response status")]
|
#[display(fmt = "Invalid response status")]
|
||||||
InvalidResponseStatus(StatusCode),
|
InvalidResponseStatus(StatusCode),
|
||||||
/// Invalid upgrade header
|
/// Invalid upgrade header
|
||||||
#[fail(display = "Invalid upgrade header")]
|
#[display(fmt = "Invalid upgrade header")]
|
||||||
InvalidUpgradeHeader,
|
InvalidUpgradeHeader,
|
||||||
/// Invalid connection header
|
/// Invalid connection header
|
||||||
#[fail(display = "Invalid connection header")]
|
#[display(fmt = "Invalid connection header")]
|
||||||
InvalidConnectionHeader(HeaderValue),
|
InvalidConnectionHeader(HeaderValue),
|
||||||
/// Missing CONNECTION header
|
/// Missing CONNECTION header
|
||||||
#[fail(display = "Missing CONNECTION header")]
|
#[display(fmt = "Missing CONNECTION header")]
|
||||||
MissingConnectionHeader,
|
MissingConnectionHeader,
|
||||||
/// Missing SEC-WEBSOCKET-ACCEPT header
|
/// Missing SEC-WEBSOCKET-ACCEPT header
|
||||||
#[fail(display = "Missing SEC-WEBSOCKET-ACCEPT header")]
|
#[display(fmt = "Missing SEC-WEBSOCKET-ACCEPT header")]
|
||||||
MissingWebSocketAcceptHeader,
|
MissingWebSocketAcceptHeader,
|
||||||
/// Invalid challenge response
|
/// Invalid challenge response
|
||||||
#[fail(display = "Invalid challenge response")]
|
#[display(fmt = "Invalid challenge response")]
|
||||||
InvalidChallengeResponse(String, HeaderValue),
|
InvalidChallengeResponse(String, HeaderValue),
|
||||||
/// Http parsing error
|
/// Http parsing error
|
||||||
#[fail(display = "Http parsing error")]
|
#[display(fmt = "Http parsing error")]
|
||||||
Http(#[cause] HttpError),
|
Http(HttpError),
|
||||||
/// Response parsing error
|
/// Response parsing error
|
||||||
#[fail(display = "Response parsing error: {}", _0)]
|
#[display(fmt = "Response parsing error: {}", _0)]
|
||||||
ParseError(#[cause] ParseError),
|
ParseError(ParseError),
|
||||||
/// Protocol error
|
/// Protocol error
|
||||||
#[fail(display = "{}", _0)]
|
#[display(fmt = "{}", _0)]
|
||||||
Protocol(#[cause] ProtocolError),
|
Protocol(ProtocolError),
|
||||||
/// Connect error
|
/// Connect error
|
||||||
#[fail(display = "Connector error: {:?}", _0)]
|
#[display(fmt = "Connector error: {:?}", _0)]
|
||||||
Connect(ConnectorError),
|
Connect(ConnectorError),
|
||||||
/// IO Error
|
/// IO Error
|
||||||
#[fail(display = "{}", _0)]
|
#[display(fmt = "{}", _0)]
|
||||||
Io(#[cause] io::Error),
|
Io(io::Error),
|
||||||
/// "Disconnected"
|
/// "Disconnected"
|
||||||
#[fail(display = "Disconnected")]
|
#[display(fmt = "Disconnected")]
|
||||||
Disconnected,
|
Disconnected,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<HttpError> for ClientError {
|
|
||||||
fn from(err: HttpError) -> ClientError {
|
|
||||||
ClientError::Http(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ConnectorError> for ClientError {
|
|
||||||
fn from(err: ConnectorError) -> ClientError {
|
|
||||||
ClientError::Connect(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ProtocolError> for ClientError {
|
|
||||||
fn from(err: ProtocolError) -> ClientError {
|
|
||||||
ClientError::Protocol(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for ClientError {
|
|
||||||
fn from(err: io::Error) -> ClientError {
|
|
||||||
ClientError::Io(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ParseError> for ClientError {
|
|
||||||
fn from(err: ParseError) -> ClientError {
|
|
||||||
ClientError::ParseError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//! communicate with the peer.
|
//! communicate with the peer.
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use failure::Fail;
|
use derive_more::{Display, From};
|
||||||
use http::{header, Method, StatusCode};
|
use http::{header, Method, StatusCode};
|
||||||
|
|
||||||
use crate::error::ResponseError;
|
use crate::error::ResponseError;
|
||||||
@ -28,65 +28,59 @@ pub use self::service::VerifyWebSockets;
|
|||||||
pub use self::transport::Transport;
|
pub use self::transport::Transport;
|
||||||
|
|
||||||
/// Websocket protocol errors
|
/// Websocket protocol errors
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Debug, Display, From)]
|
||||||
pub enum ProtocolError {
|
pub enum ProtocolError {
|
||||||
/// Received an unmasked frame from client
|
/// Received an unmasked frame from client
|
||||||
#[fail(display = "Received an unmasked frame from client")]
|
#[display(fmt = "Received an unmasked frame from client")]
|
||||||
UnmaskedFrame,
|
UnmaskedFrame,
|
||||||
/// Received a masked frame from server
|
/// Received a masked frame from server
|
||||||
#[fail(display = "Received a masked frame from server")]
|
#[display(fmt = "Received a masked frame from server")]
|
||||||
MaskedFrame,
|
MaskedFrame,
|
||||||
/// Encountered invalid opcode
|
/// Encountered invalid opcode
|
||||||
#[fail(display = "Invalid opcode: {}", _0)]
|
#[display(fmt = "Invalid opcode: {}", _0)]
|
||||||
InvalidOpcode(u8),
|
InvalidOpcode(u8),
|
||||||
/// Invalid control frame length
|
/// Invalid control frame length
|
||||||
#[fail(display = "Invalid control frame length: {}", _0)]
|
#[display(fmt = "Invalid control frame length: {}", _0)]
|
||||||
InvalidLength(usize),
|
InvalidLength(usize),
|
||||||
/// Bad web socket op code
|
/// Bad web socket op code
|
||||||
#[fail(display = "Bad web socket op code")]
|
#[display(fmt = "Bad web socket op code")]
|
||||||
BadOpCode,
|
BadOpCode,
|
||||||
/// A payload reached size limit.
|
/// A payload reached size limit.
|
||||||
#[fail(display = "A payload reached size limit.")]
|
#[display(fmt = "A payload reached size limit.")]
|
||||||
Overflow,
|
Overflow,
|
||||||
/// Continuation is not supported
|
/// Continuation is not supported
|
||||||
#[fail(display = "Continuation is not supported.")]
|
#[display(fmt = "Continuation is not supported.")]
|
||||||
NoContinuation,
|
NoContinuation,
|
||||||
/// Bad utf-8 encoding
|
/// Bad utf-8 encoding
|
||||||
#[fail(display = "Bad utf-8 encoding.")]
|
#[display(fmt = "Bad utf-8 encoding.")]
|
||||||
BadEncoding,
|
BadEncoding,
|
||||||
/// Io error
|
/// Io error
|
||||||
#[fail(display = "io error: {}", _0)]
|
#[display(fmt = "io error: {}", _0)]
|
||||||
Io(#[cause] io::Error),
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseError for ProtocolError {}
|
impl ResponseError for ProtocolError {}
|
||||||
|
|
||||||
impl From<io::Error> for ProtocolError {
|
|
||||||
fn from(err: io::Error) -> ProtocolError {
|
|
||||||
ProtocolError::Io(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Websocket handshake errors
|
/// Websocket handshake errors
|
||||||
#[derive(Fail, PartialEq, Debug)]
|
#[derive(PartialEq, Debug, Display)]
|
||||||
pub enum HandshakeError {
|
pub enum HandshakeError {
|
||||||
/// Only get method is allowed
|
/// Only get method is allowed
|
||||||
#[fail(display = "Method not allowed")]
|
#[display(fmt = "Method not allowed")]
|
||||||
GetMethodRequired,
|
GetMethodRequired,
|
||||||
/// Upgrade header if not set to websocket
|
/// Upgrade header if not set to websocket
|
||||||
#[fail(display = "Websocket upgrade is expected")]
|
#[display(fmt = "Websocket upgrade is expected")]
|
||||||
NoWebsocketUpgrade,
|
NoWebsocketUpgrade,
|
||||||
/// Connection header is not set to upgrade
|
/// Connection header is not set to upgrade
|
||||||
#[fail(display = "Connection upgrade is expected")]
|
#[display(fmt = "Connection upgrade is expected")]
|
||||||
NoConnectionUpgrade,
|
NoConnectionUpgrade,
|
||||||
/// Websocket version header is not set
|
/// Websocket version header is not set
|
||||||
#[fail(display = "Websocket version header is required")]
|
#[display(fmt = "Websocket version header is required")]
|
||||||
NoVersionHeader,
|
NoVersionHeader,
|
||||||
/// Unsupported websocket version
|
/// Unsupported websocket version
|
||||||
#[fail(display = "Unsupported version")]
|
#[display(fmt = "Unsupported version")]
|
||||||
UnsupportedVersion,
|
UnsupportedVersion,
|
||||||
/// Websocket key is not set or wrong
|
/// Websocket key is not set or wrong
|
||||||
#[fail(display = "Unknown websocket key")]
|
#[display(fmt = "Unknown websocket key")]
|
||||||
BadWebsocketKey,
|
BadWebsocketKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user