mirror of
https://github.com/fafhrd91/actix-web
synced 2025-06-26 15:07:42 +02:00
refined error model (#2253)
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
use std::{
|
||||
cell::Cell,
|
||||
convert::Infallible,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use actix_codec::{AsyncRead, AsyncWrite, Framed};
|
||||
use actix_http::{
|
||||
body::BodySize,
|
||||
body::{AnyBody, BodySize},
|
||||
h1,
|
||||
ws::{self, CloseCode, Frame, Item, Message},
|
||||
Error, HttpService, Request, Response,
|
||||
@ -13,6 +14,7 @@ use actix_http::{
|
||||
use actix_http_test::test_server;
|
||||
use actix_service::{fn_factory, Service};
|
||||
use bytes::Bytes;
|
||||
use derive_more::{Display, Error, From};
|
||||
use futures_core::future::LocalBoxFuture;
|
||||
use futures_util::{SinkExt as _, StreamExt as _};
|
||||
|
||||
@ -33,12 +35,39 @@ impl WsService {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Error, From)]
|
||||
enum WsServiceError {
|
||||
#[display(fmt = "http error")]
|
||||
Http(actix_http::Error),
|
||||
|
||||
#[display(fmt = "ws handshake error")]
|
||||
Ws(actix_http::ws::HandshakeError),
|
||||
|
||||
#[display(fmt = "io error")]
|
||||
Io(std::io::Error),
|
||||
|
||||
#[display(fmt = "dispatcher error")]
|
||||
Dispatcher,
|
||||
}
|
||||
|
||||
impl From<WsServiceError> for Response<AnyBody> {
|
||||
fn from(err: WsServiceError) -> Self {
|
||||
match err {
|
||||
WsServiceError::Http(err) => err.into(),
|
||||
WsServiceError::Ws(err) => err.into(),
|
||||
WsServiceError::Io(_err) => unreachable!(),
|
||||
WsServiceError::Dispatcher => Response::internal_server_error()
|
||||
.set_body(AnyBody::from(format!("{}", err))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Service<(Request, Framed<T, h1::Codec>)> for WsService
|
||||
where
|
||||
T: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||
{
|
||||
type Response = ();
|
||||
type Error = Error;
|
||||
type Error = WsServiceError;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
@ -56,7 +85,9 @@ where
|
||||
|
||||
let framed = framed.replace_codec(ws::Codec::new());
|
||||
|
||||
ws::Dispatcher::with(framed, service).await?;
|
||||
ws::Dispatcher::with(framed, service)
|
||||
.await
|
||||
.map_err(|_| WsServiceError::Dispatcher)?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
@ -72,7 +103,7 @@ async fn service(msg: Frame) -> Result<Message, Error> {
|
||||
Frame::Binary(bin) => Message::Binary(bin),
|
||||
Frame::Continuation(item) => Message::Continuation(item),
|
||||
Frame::Close(reason) => Message::Close(reason),
|
||||
_ => return Err(Error::from(ws::ProtocolError::BadOpCode)),
|
||||
_ => return Err(ws::ProtocolError::BadOpCode.into()),
|
||||
};
|
||||
|
||||
Ok(msg)
|
||||
@ -82,8 +113,10 @@ async fn service(msg: Frame) -> Result<Message, Error> {
|
||||
async fn test_simple() {
|
||||
let mut srv = test_server(|| {
|
||||
HttpService::build()
|
||||
.upgrade(fn_factory(|| async { Ok::<_, ()>(WsService::new()) }))
|
||||
.finish(|_| async { Ok::<_, ()>(Response::not_found()) })
|
||||
.upgrade(fn_factory(|| async {
|
||||
Ok::<_, Infallible>(WsService::new())
|
||||
}))
|
||||
.finish(|_| async { Ok::<_, Infallible>(Response::not_found()) })
|
||||
.tcp()
|
||||
})
|
||||
.await;
|
||||
|
Reference in New Issue
Block a user