mirror of https://github.com/fafhrd91/actix-web
http: Convert from `derive_more` to `thiserror`
The `thiserror` has the advantage of implementing `std::error::Error` and it integrates better with the Rust ecosystem. Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
This commit is contained in:
parent
9f196fe5a5
commit
d2259b57dc
|
@ -56,7 +56,6 @@ base64 = "0.11"
|
|||
bitflags = "1.2"
|
||||
bytes = "0.5.3"
|
||||
copyless = "0.1.4"
|
||||
derive_more = "0.99.2"
|
||||
either = "1.5.3"
|
||||
encoding_rs = "0.8"
|
||||
futures-core = "0.3.1"
|
||||
|
@ -80,6 +79,7 @@ serde_json = "1.0"
|
|||
sha-1 = "0.8"
|
||||
slab = "0.4"
|
||||
serde_urlencoded = "0.6.1"
|
||||
thiserror = "1.0.11"
|
||||
time = { version = "0.2.7", default-features = false, features = ["std"] }
|
||||
|
||||
# for secure cookie
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::io;
|
||||
|
||||
use actix_connect::resolver::ResolveError;
|
||||
use derive_more::{Display, From};
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
use actix_connect::ssl::openssl::{HandshakeError, SslError};
|
||||
|
@ -10,49 +10,49 @@ use crate::error::{Error, ParseError, ResponseError};
|
|||
use crate::http::{Error as HttpError, StatusCode};
|
||||
|
||||
/// A set of errors that can occur while connecting to an HTTP host
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ConnectError {
|
||||
/// SSL feature is not enabled
|
||||
#[display(fmt = "SSL is not supported")]
|
||||
#[error("SSL is not supported")]
|
||||
SslIsNotSupported,
|
||||
|
||||
/// SSL error
|
||||
#[cfg(feature = "openssl")]
|
||||
#[display(fmt = "{}", _0)]
|
||||
SslError(SslError),
|
||||
#[error(transparent)]
|
||||
SslError(#[from] SslError),
|
||||
|
||||
/// SSL Handshake error
|
||||
#[cfg(feature = "openssl")]
|
||||
#[display(fmt = "{}", _0)]
|
||||
#[error("SSL handshake error: {0}")]
|
||||
SslHandshakeError(String),
|
||||
|
||||
/// Failed to resolve the hostname
|
||||
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
||||
Resolver(ResolveError),
|
||||
#[error("Failed resolving hostname: {0}")]
|
||||
Resolver(#[from] ResolveError),
|
||||
|
||||
/// No dns records
|
||||
#[display(fmt = "No dns records found for the input")]
|
||||
#[error("No dns records found for the input")]
|
||||
NoRecords,
|
||||
|
||||
/// Http2 error
|
||||
#[display(fmt = "{}", _0)]
|
||||
H2(h2::Error),
|
||||
#[error(transparent)]
|
||||
H2(#[from] h2::Error),
|
||||
|
||||
/// Connecting took too long
|
||||
#[display(fmt = "Timeout out while establishing connection")]
|
||||
#[error("Timeout out while establishing connection")]
|
||||
Timeout,
|
||||
|
||||
/// Connector has been disconnected
|
||||
#[display(fmt = "Internal error: connector has been disconnected")]
|
||||
#[error("Internal error: connector has been disconnected")]
|
||||
Disconnected,
|
||||
|
||||
/// Unresolved host name
|
||||
#[display(fmt = "Connector received `Connect` method with unresolved host")]
|
||||
#[error("Connector received `Connect` method with unresolved host")]
|
||||
Unresolverd,
|
||||
|
||||
/// Connection io error
|
||||
#[display(fmt = "{}", _0)]
|
||||
Io(io::Error),
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
}
|
||||
|
||||
impl From<actix_connect::ConnectError> for ConnectError {
|
||||
|
@ -74,45 +74,48 @@ impl<T: std::fmt::Debug> From<HandshakeError<T>> for ConnectError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InvalidUrl {
|
||||
#[display(fmt = "Missing url scheme")]
|
||||
#[error("Missing url scheme")]
|
||||
MissingScheme,
|
||||
#[display(fmt = "Unknown url scheme")]
|
||||
#[error("Unknown url scheme")]
|
||||
UnknownScheme,
|
||||
#[display(fmt = "Missing host name")]
|
||||
#[error("Missing host name")]
|
||||
MissingHost,
|
||||
#[display(fmt = "Url parse error: {}", _0)]
|
||||
HttpError(http::Error),
|
||||
#[error("Url parse error: {0}")]
|
||||
HttpError(#[from] http::Error),
|
||||
}
|
||||
|
||||
/// A set of errors that can occur during request sending and response reading
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SendRequestError {
|
||||
/// Invalid URL
|
||||
#[display(fmt = "Invalid URL: {}", _0)]
|
||||
Url(InvalidUrl),
|
||||
#[error("Invalid URL: {0}")]
|
||||
Url(#[from] InvalidUrl),
|
||||
/// Failed to connect to host
|
||||
#[display(fmt = "Failed to connect to host: {}", _0)]
|
||||
Connect(ConnectError),
|
||||
#[error("Failed to connect to host: {0}")]
|
||||
Connect(#[from] ConnectError),
|
||||
/// Error sending request
|
||||
Send(io::Error),
|
||||
#[error(transparent)]
|
||||
Send(#[from] io::Error),
|
||||
/// Error parsing response
|
||||
Response(ParseError),
|
||||
#[error(transparent)]
|
||||
Response(#[from] ParseError),
|
||||
/// Http error
|
||||
#[display(fmt = "{}", _0)]
|
||||
Http(HttpError),
|
||||
#[error(transparent)]
|
||||
Http(#[from] HttpError),
|
||||
/// Http2 error
|
||||
#[display(fmt = "{}", _0)]
|
||||
H2(h2::Error),
|
||||
#[error(transparent)]
|
||||
H2(#[from] h2::Error),
|
||||
/// Response took too long
|
||||
#[display(fmt = "Timeout out while waiting for response")]
|
||||
#[error("Timeout out while waiting for response")]
|
||||
Timeout,
|
||||
/// Tunnels are not supported for http2 connection
|
||||
#[display(fmt = "Tunnels are not supported for http2 connection")]
|
||||
#[error("Tunnels are not supported for http2 connection")]
|
||||
TunnelNotSupported,
|
||||
/// Error sending request body
|
||||
Body(Error),
|
||||
#[error(transparent)]
|
||||
Body(#[from] Error),
|
||||
}
|
||||
|
||||
/// Convert `SendRequestError` to a server `Response`
|
||||
|
@ -129,21 +132,12 @@ impl ResponseError for SendRequestError {
|
|||
}
|
||||
|
||||
/// A set of errors that can occur during freezing a request
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FreezeRequestError {
|
||||
/// Invalid URL
|
||||
#[display(fmt = "Invalid URL: {}", _0)]
|
||||
Url(InvalidUrl),
|
||||
#[error("Invalid URL: {0}")]
|
||||
Url(#[from] InvalidUrl),
|
||||
/// Http error
|
||||
#[display(fmt = "{}", _0)]
|
||||
Http(HttpError),
|
||||
}
|
||||
|
||||
impl From<FreezeRequestError> for SendRequestError {
|
||||
fn from(e: FreezeRequestError) -> Self {
|
||||
match e {
|
||||
FreezeRequestError::Url(e) => e.into(),
|
||||
FreezeRequestError::Http(e) => e.into(),
|
||||
}
|
||||
}
|
||||
#[error(transparent)]
|
||||
Http(#[from] HttpError),
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::io::Write;
|
||||
use std::str::Utf8Error;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::{fmt, io, result};
|
||||
|
||||
use actix_codec::{Decoder, Encoder};
|
||||
|
@ -10,13 +9,13 @@ pub use actix_threadpool::BlockingError;
|
|||
use actix_utils::framed::DispatcherError as FramedDispatcherError;
|
||||
use actix_utils::timeout::TimeoutError;
|
||||
use bytes::BytesMut;
|
||||
use derive_more::{Display, From};
|
||||
pub use futures_channel::oneshot::Canceled;
|
||||
use http::uri::InvalidUri;
|
||||
use http::{header, Error as HttpError, StatusCode};
|
||||
use serde::de::value::Error as DeError;
|
||||
use serde_json::error::Error as JsonError;
|
||||
use serde_urlencoded::ser::Error as FormError;
|
||||
use thiserror::Error;
|
||||
|
||||
// re-export for convinience
|
||||
use crate::body::Body;
|
||||
|
@ -42,6 +41,7 @@ pub type Result<T, E = Error> = result::Result<T, E>;
|
|||
/// for it that can be used to create an http response from it this means that
|
||||
/// if you have access to an actix `Error` you can always get a
|
||||
/// `ResponseError` reference from it.
|
||||
#[derive(Error)]
|
||||
pub struct Error {
|
||||
cause: Box<dyn ResponseError>,
|
||||
}
|
||||
|
@ -98,16 +98,6 @@ impl fmt::Debug for Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn cause(&self) -> Option<&dyn std::error::Error> {
|
||||
None
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl From<()> for Error {
|
||||
fn from(_: ()) -> Self {
|
||||
Error::from(UnitError)
|
||||
|
@ -162,8 +152,8 @@ impl<E: ResponseError> ResponseError for TimeoutError<E> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
#[display(fmt = "UnknownError")]
|
||||
#[derive(Debug, Error)]
|
||||
#[error("UnknownError")]
|
||||
struct UnitError;
|
||||
|
||||
/// `InternalServerError` for `UnitError`
|
||||
|
@ -226,40 +216,40 @@ impl ResponseError for header::InvalidHeaderValue {
|
|||
}
|
||||
|
||||
/// A set of errors that can occur during parsing HTTP streams
|
||||
#[derive(Debug, Display)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ParseError {
|
||||
/// An invalid `Method`, such as `GE.T`.
|
||||
#[display(fmt = "Invalid Method specified")]
|
||||
#[error("Invalid Method specified")]
|
||||
Method,
|
||||
/// An invalid `Uri`, such as `exam ple.domain`.
|
||||
#[display(fmt = "Uri error: {}", _0)]
|
||||
Uri(InvalidUri),
|
||||
#[error("Uri error: {0}")]
|
||||
Uri(#[from] InvalidUri),
|
||||
/// An invalid `HttpVersion`, such as `HTP/1.1`
|
||||
#[display(fmt = "Invalid HTTP version specified")]
|
||||
#[error("Invalid HTTP version specified")]
|
||||
Version,
|
||||
/// An invalid `Header`.
|
||||
#[display(fmt = "Invalid Header provided")]
|
||||
#[error("Invalid Header provided")]
|
||||
Header,
|
||||
/// A message head is too large to be reasonable.
|
||||
#[display(fmt = "Message head is too large")]
|
||||
#[error("Message head is too large")]
|
||||
TooLarge,
|
||||
/// A message reached EOF, but is not complete.
|
||||
#[display(fmt = "Message is incomplete")]
|
||||
#[error("Message is incomplete")]
|
||||
Incomplete,
|
||||
/// An invalid `Status`, such as `1337 ELITE`.
|
||||
#[display(fmt = "Invalid Status provided")]
|
||||
#[error("Invalid Status provided")]
|
||||
Status,
|
||||
/// A timeout occurred waiting for an IO event.
|
||||
#[allow(dead_code)]
|
||||
#[display(fmt = "Timeout")]
|
||||
#[error("Timeout")]
|
||||
Timeout,
|
||||
/// An `io::Error` that occurred while trying to read or write to a network
|
||||
/// stream.
|
||||
#[display(fmt = "IO error: {}", _0)]
|
||||
Io(io::Error),
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
/// Parsing a field as string failed
|
||||
#[display(fmt = "UTF8 error: {}", _0)]
|
||||
Utf8(Utf8Error),
|
||||
#[error("UTF8 error: {0}")]
|
||||
Utf8(#[from] Utf8Error),
|
||||
}
|
||||
|
||||
/// Return `BadRequest` for `ParseError`
|
||||
|
@ -269,30 +259,6 @@ impl ResponseError for ParseError {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for ParseError {
|
||||
fn from(err: io::Error) -> ParseError {
|
||||
ParseError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InvalidUri> for ParseError {
|
||||
fn from(err: InvalidUri) -> ParseError {
|
||||
ParseError::Uri(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Utf8Error> for ParseError {
|
||||
fn from(err: Utf8Error) -> ParseError {
|
||||
ParseError::Utf8(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FromUtf8Error> for ParseError {
|
||||
fn from(err: FromUtf8Error) -> ParseError {
|
||||
ParseError::Utf8(err.utf8_error())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<httparse::Error> for ParseError {
|
||||
fn from(err: httparse::Error) -> ParseError {
|
||||
match err {
|
||||
|
@ -307,48 +273,27 @@ impl From<httparse::Error> for ParseError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Display, Debug)]
|
||||
#[derive(Error, Debug)]
|
||||
/// A set of errors that can occur during payload parsing
|
||||
pub enum PayloadError {
|
||||
/// A payload reached EOF, but is not complete.
|
||||
#[display(
|
||||
fmt = "A payload reached EOF, but is not complete. With error: {:?}",
|
||||
_0
|
||||
)]
|
||||
Incomplete(Option<io::Error>),
|
||||
#[error("A payload reached EOF, but is not complete. With error: {0:?}")]
|
||||
Incomplete(#[from] Option<io::Error>),
|
||||
/// Content encoding stream corruption
|
||||
#[display(fmt = "Can not decode content-encoding.")]
|
||||
#[error("Can not decode content-encoding.")]
|
||||
EncodingCorrupted,
|
||||
/// A payload reached size limit.
|
||||
#[display(fmt = "A payload reached size limit.")]
|
||||
#[error("A payload reached size limit.")]
|
||||
Overflow,
|
||||
/// A payload length is unknown.
|
||||
#[display(fmt = "A payload length is unknown.")]
|
||||
#[error("A payload length is unknown.")]
|
||||
UnknownLength,
|
||||
/// Http2 payload error
|
||||
#[display(fmt = "{}", _0)]
|
||||
Http2Payload(h2::Error),
|
||||
#[error(transparent)]
|
||||
Http2Payload(#[from] h2::Error),
|
||||
/// Io error
|
||||
#[display(fmt = "{}", _0)]
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
impl From<h2::Error> for PayloadError {
|
||||
fn from(err: h2::Error) -> Self {
|
||||
PayloadError::Http2Payload(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<io::Error>> for PayloadError {
|
||||
fn from(err: Option<io::Error>) -> Self {
|
||||
PayloadError::Incomplete(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for PayloadError {
|
||||
fn from(err: io::Error) -> Self {
|
||||
PayloadError::Incomplete(Some(err))
|
||||
}
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
}
|
||||
|
||||
impl From<BlockingError<io::Error>> for PayloadError {
|
||||
|
@ -383,61 +328,63 @@ impl ResponseError for crate::cookie::ParseError {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
/// A set of errors that can occur during dispatching http requests
|
||||
pub enum DispatchError {
|
||||
/// Service error
|
||||
Service(Error),
|
||||
#[error(transparent)]
|
||||
Service(#[from] Error),
|
||||
|
||||
/// Upgrade service error
|
||||
#[error("Upgrade service error")]
|
||||
Upgrade,
|
||||
|
||||
/// An `io::Error` that occurred while trying to read or write to a network
|
||||
/// stream.
|
||||
#[display(fmt = "IO error: {}", _0)]
|
||||
Io(io::Error),
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
|
||||
/// Http request parse error.
|
||||
#[display(fmt = "Parse error: {}", _0)]
|
||||
Parse(ParseError),
|
||||
#[error("Parse error: {0}")]
|
||||
Parse(#[from] ParseError),
|
||||
|
||||
/// Http/2 error
|
||||
#[display(fmt = "{}", _0)]
|
||||
H2(h2::Error),
|
||||
#[error(transparent)]
|
||||
H2(#[from] h2::Error),
|
||||
|
||||
/// The first request did not complete within the specified timeout.
|
||||
#[display(fmt = "The first request did not complete within the specified timeout")]
|
||||
#[error("The first request did not complete within the specified timeout")]
|
||||
SlowRequestTimeout,
|
||||
|
||||
/// Disconnect timeout. Makes sense for ssl streams.
|
||||
#[display(fmt = "Connection shutdown timeout")]
|
||||
#[error("Connection shutdown timeout")]
|
||||
DisconnectTimeout,
|
||||
|
||||
/// Payload is not consumed
|
||||
#[display(fmt = "Task is completed but request's payload is not consumed")]
|
||||
#[error("Task is completed but request's payload is not consumed")]
|
||||
PayloadIsNotConsumed,
|
||||
|
||||
/// Malformed request
|
||||
#[display(fmt = "Malformed request")]
|
||||
#[error("Malformed request")]
|
||||
MalformedRequest,
|
||||
|
||||
/// Internal error
|
||||
#[display(fmt = "Internal error")]
|
||||
#[error("Internal error")]
|
||||
InternalError,
|
||||
|
||||
/// Unknown error
|
||||
#[display(fmt = "Unknown error")]
|
||||
#[error("Unknown error")]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// A set of error that can occure during parsing content type
|
||||
#[derive(PartialEq, Debug, Display)]
|
||||
#[derive(Error, PartialEq, Debug)]
|
||||
pub enum ContentTypeError {
|
||||
/// Can not parse content type
|
||||
#[display(fmt = "Can not parse content type")]
|
||||
#[error("Can not parse content type")]
|
||||
ParseError,
|
||||
/// Unknown content encoding
|
||||
#[display(fmt = "Unknown content encoding")]
|
||||
#[error("Unknown content encoding")]
|
||||
UnknownEncoding,
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
//! communicate with the peer.
|
||||
use std::io;
|
||||
|
||||
use derive_more::{Display, From};
|
||||
use http::{header, Method, StatusCode};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::error::ResponseError;
|
||||
use crate::message::RequestHead;
|
||||
|
@ -24,62 +24,62 @@ pub use self::frame::Parser;
|
|||
pub use self::proto::{hash_key, CloseCode, CloseReason, OpCode};
|
||||
|
||||
/// Websocket protocol errors
|
||||
#[derive(Debug, Display, From)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProtocolError {
|
||||
/// Received an unmasked frame from client
|
||||
#[display(fmt = "Received an unmasked frame from client")]
|
||||
#[error("Received an unmasked frame from client")]
|
||||
UnmaskedFrame,
|
||||
/// Received a masked frame from server
|
||||
#[display(fmt = "Received a masked frame from server")]
|
||||
#[error("Received a masked frame from server")]
|
||||
MaskedFrame,
|
||||
/// Encountered invalid opcode
|
||||
#[display(fmt = "Invalid opcode: {}", _0)]
|
||||
#[error("Invalid opcode: {0}")]
|
||||
InvalidOpcode(u8),
|
||||
/// Invalid control frame length
|
||||
#[display(fmt = "Invalid control frame length: {}", _0)]
|
||||
#[error("Invalid control frame length: {0}")]
|
||||
InvalidLength(usize),
|
||||
/// Bad web socket op code
|
||||
#[display(fmt = "Bad web socket op code")]
|
||||
#[error("Bad web socket op code")]
|
||||
BadOpCode,
|
||||
/// A payload reached size limit.
|
||||
#[display(fmt = "A payload reached size limit.")]
|
||||
#[error("A payload reached size limit.")]
|
||||
Overflow,
|
||||
/// Continuation is not started
|
||||
#[display(fmt = "Continuation is not started.")]
|
||||
#[error("Continuation is not started.")]
|
||||
ContinuationNotStarted,
|
||||
/// Received new continuation but it is already started
|
||||
#[display(fmt = "Received new continuation but it is already started")]
|
||||
#[error("Received new continuation but it is already started")]
|
||||
ContinuationStarted,
|
||||
/// Unknown continuation fragment
|
||||
#[display(fmt = "Unknown continuation fragment.")]
|
||||
#[error("Unknown continuation fragment.")]
|
||||
ContinuationFragment(OpCode),
|
||||
/// Io error
|
||||
#[display(fmt = "io error: {}", _0)]
|
||||
Io(io::Error),
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
}
|
||||
|
||||
impl ResponseError for ProtocolError {}
|
||||
|
||||
/// Websocket handshake errors
|
||||
#[derive(PartialEq, Debug, Display)]
|
||||
#[derive(PartialEq, Debug, Error)]
|
||||
pub enum HandshakeError {
|
||||
/// Only get method is allowed
|
||||
#[display(fmt = "Method not allowed")]
|
||||
#[error("Method not allowed")]
|
||||
GetMethodRequired,
|
||||
/// Upgrade header if not set to websocket
|
||||
#[display(fmt = "Websocket upgrade is expected")]
|
||||
#[error("Websocket upgrade is expected")]
|
||||
NoWebsocketUpgrade,
|
||||
/// Connection header is not set to upgrade
|
||||
#[display(fmt = "Connection upgrade is expected")]
|
||||
#[error("Connection upgrade is expected")]
|
||||
NoConnectionUpgrade,
|
||||
/// Websocket version header is not set
|
||||
#[display(fmt = "Websocket version header is required")]
|
||||
#[error("Websocket version header is required")]
|
||||
NoVersionHeader,
|
||||
/// Unsupported websocket version
|
||||
#[display(fmt = "Unsupported version")]
|
||||
#[error("Unsupported version")]
|
||||
UnsupportedVersion,
|
||||
/// Websocket key is not set or wrong
|
||||
#[display(fmt = "Unknown websocket key")]
|
||||
#[error("Unknown websocket key")]
|
||||
BadWebsocketKey,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue