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