Add axum::Error (#150)

Replace `BoxStdError` and supports downcasting
This commit is contained in:
David Pedersen
2021-08-07 19:56:44 +02:00
committed by GitHub
parent 4792d0c15c
commit 75b5615ccd
12 changed files with 88 additions and 65 deletions
+2 -1
View File
@@ -4,6 +4,7 @@ use bytes::Buf;
use http::Method;
use serde::de::DeserializeOwned;
use std::ops::Deref;
use tower::BoxError;
/// Extractor that deserializes `application/x-www-form-urlencoded` requests
/// into some type.
@@ -44,7 +45,7 @@ where
T: DeserializeOwned,
B: http_body::Body + Send,
B::Data: Send,
B::Error: Into<tower::BoxError>,
B::Error: Into<BoxError>,
{
type Rejection = FormRejection;
+11 -8
View File
@@ -1,7 +1,10 @@
//! Rejection response types.
use super::IntoResponse;
use crate::body::{box_body, BoxBody, BoxStdError};
use crate::{
body::{box_body, BoxBody},
Error,
};
use bytes::Bytes;
use http_body::Full;
use std::convert::Infallible;
@@ -46,7 +49,7 @@ define_rejection! {
#[status = BAD_REQUEST]
#[body = "Failed to parse the request body as JSON"]
/// Rejection type for [`Json`](super::Json).
pub struct InvalidJsonBody(BoxError);
pub struct InvalidJsonBody(Error);
}
define_rejection! {
@@ -62,7 +65,7 @@ define_rejection! {
#[body = "Missing request extension"]
/// Rejection type for [`Extension`](super::Extension) if an expected
/// request extension was not found.
pub struct MissingExtension(BoxError);
pub struct MissingExtension(Error);
}
define_rejection! {
@@ -70,7 +73,7 @@ define_rejection! {
#[body = "Failed to buffer the request body"]
/// Rejection type for extractors that buffer the request body. Used if the
/// request body cannot be buffered due to an error.
pub struct FailedToBufferBody(BoxError);
pub struct FailedToBufferBody(Error);
}
define_rejection! {
@@ -78,7 +81,7 @@ define_rejection! {
#[body = "Request body didn't contain valid UTF-8"]
/// Rejection type used when buffering the request into a [`String`] if the
/// body doesn't contain valid UTF-8.
pub struct InvalidUtf8(BoxError);
pub struct InvalidUtf8(Error);
}
define_rejection! {
@@ -183,7 +186,7 @@ impl IntoResponse for InvalidPathParam {
/// couldn't be deserialized into the target type.
#[derive(Debug)]
pub struct FailedToDeserializeQueryString {
error: BoxError,
error: Error,
type_name: &'static str,
}
@@ -193,7 +196,7 @@ impl FailedToDeserializeQueryString {
E: Into<BoxError>,
{
FailedToDeserializeQueryString {
error: error.into(),
error: Error::new(error),
type_name: std::any::type_name::<T>(),
}
}
@@ -330,7 +333,7 @@ where
T: IntoResponse,
{
type Body = BoxBody;
type BodyError = BoxStdError;
type BodyError = Error;
fn into_response(self) -> http::Response<Self::Body> {
match self {
+3 -2
View File
@@ -7,6 +7,7 @@ use std::{
pin::Pin,
task::{Context, Poll},
};
use tower::BoxError;
#[async_trait]
impl<B> FromRequest<B> for Request<B>
@@ -176,7 +177,7 @@ impl<B> FromRequest<B> for Bytes
where
B: http_body::Body + Send,
B::Data: Send,
B::Error: Into<tower::BoxError>,
B::Error: Into<BoxError>,
{
type Rejection = BytesRejection;
@@ -196,7 +197,7 @@ impl<B> FromRequest<B> for String
where
B: http_body::Body + Send,
B::Data: Send,
B::Error: Into<tower::BoxError>,
B::Error: Into<BoxError>,
{
type Rejection = StringRejection;
+19 -20
View File
@@ -37,7 +37,7 @@
use self::rejection::*;
use super::{rejection::*, FromRequest, RequestParts};
use crate::response::IntoResponse;
use crate::{response::IntoResponse, Error};
use async_trait::async_trait;
use bytes::Bytes;
use futures_util::{
@@ -64,7 +64,6 @@ use tokio_tungstenite::{
},
WebSocketStream,
};
use tower::BoxError;
/// Extractor for establishing WebSocket connections.
///
@@ -332,32 +331,32 @@ impl WebSocket {
/// Receive another message.
///
/// Returns `None` if the stream stream has closed.
pub async fn recv(&mut self) -> Option<Result<Message, BoxError>> {
pub async fn recv(&mut self) -> Option<Result<Message, Error>> {
self.next().await
}
/// Send a message.
pub async fn send(&mut self, msg: Message) -> Result<(), BoxError> {
pub async fn send(&mut self, msg: Message) -> Result<(), Error> {
self.inner
.send(msg.into_tungstenite())
.await
.map_err(Into::into)
.map_err(Error::new)
}
/// Gracefully close this WebSocket.
pub async fn close(mut self) -> Result<(), BoxError> {
self.inner.close(None).await.map_err(Into::into)
pub async fn close(mut self) -> Result<(), Error> {
self.inner.close(None).await.map_err(Error::new)
}
}
impl Stream for WebSocket {
type Item = Result<Message, BoxError>;
type Item = Result<Message, Error>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.inner.poll_next_unpin(cx).map(|option_msg| {
option_msg.map(|result_msg| {
result_msg
.map_err(Into::into)
.map_err(Error::new)
.map(Message::from_tungstenite)
})
})
@@ -365,24 +364,24 @@ impl Stream for WebSocket {
}
impl Sink<Message> for WebSocket {
type Error = BoxError;
type Error = Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.inner).poll_ready(cx).map_err(Into::into)
Pin::new(&mut self.inner).poll_ready(cx).map_err(Error::new)
}
fn start_send(mut self: Pin<&mut Self>, item: Message) -> Result<(), Self::Error> {
Pin::new(&mut self.inner)
.start_send(item.into_tungstenite())
.map_err(Into::into)
.map_err(Error::new)
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.inner).poll_flush(cx).map_err(Into::into)
Pin::new(&mut self.inner).poll_flush(cx).map_err(Error::new)
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.inner).poll_close(cx).map_err(Into::into)
Pin::new(&mut self.inner).poll_close(cx).map_err(Error::new)
}
}
@@ -483,12 +482,12 @@ impl Message {
}
/// Attempt to consume the WebSocket message and convert it to a String.
pub fn into_text(self) -> Result<String, BoxError> {
pub fn into_text(self) -> Result<String, Error> {
match self {
Self::Text(string) => Ok(string),
Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => {
Ok(String::from_utf8(data).map_err(|err| err.utf8_error())?)
}
Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => Ok(String::from_utf8(data)
.map_err(|err| err.utf8_error())
.map_err(Error::new)?),
Self::Close(None) => Ok(String::new()),
Self::Close(Some(frame)) => Ok(frame.reason.into_owned()),
}
@@ -496,11 +495,11 @@ impl Message {
/// Attempt to get a &str from the WebSocket message,
/// this will try to convert binary data to utf8.
pub fn to_text(&self) -> Result<&str, BoxError> {
pub fn to_text(&self) -> Result<&str, Error> {
match *self {
Self::Text(ref string) => Ok(string),
Self::Binary(ref data) | Self::Ping(ref data) | Self::Pong(ref data) => {
Ok(std::str::from_utf8(data)?)
Ok(std::str::from_utf8(data).map_err(Error::new)?)
}
Self::Close(None) => Ok(""),
Self::Close(Some(ref frame)) => Ok(&frame.reason),