1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 01:32:57 +01:00

drop failure crate

This commit is contained in:
Nikolay Kim 2018-12-19 18:34:56 -08:00
parent b1001b80b7
commit cc74435b01
6 changed files with 235 additions and 403 deletions

View File

@ -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"

View File

@ -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)
}
}

View File

@ -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() {

View File

@ -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!

View File

@ -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)
}
}

View File

@ -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,
} }