diff --git a/web/CHANGES.md b/web/CHANGES.md index d12c6217..f09d2d6d 100644 --- a/web/CHANGES.md +++ b/web/CHANGES.md @@ -1,4 +1,6 @@ -# unreleased +# unreleased 0.3.0 +## Remove +- remove `xitca_web::error::{BadRequest, Internal}` types. `xitca_web::error::ErrorStatus` replace their roles where `ErrorStatus::bad_request` and `ErrorStatus::internal` would generate identical error information as `BadRequest` and `Internal` types. this change would simplify runtime error type casting a bit with two less possible error types. # 0.2.2 ## Add diff --git a/web/Cargo.toml b/web/Cargo.toml index 52db6413..38e0e983 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xitca-web" -version = "0.2.2" +version = "0.3.0" edition = "2021" license = "Apache-2.0" description = "an async web framework" diff --git a/web/src/error.rs b/web/src/error.rs index 1c510abd..892a7565 100644 --- a/web/src/error.rs +++ b/web/src/error.rs @@ -16,12 +16,12 @@ //! # use xitca_web::{ //! # error::Error, //! # handler::{handler_service, html::Html, Responder}, -//! # http::WebResponse, +//! # http::{StatusCode, WebResponse}, //! # service::Service, //! # App, WebContext}; -//! // a handler function produce error. +//! // a handler function always produce error. //! async fn handler() -> Error { -//! Error::from_service(xitca_web::error::BadRequest) +//! Error::from(StatusCode::BAD_REQUEST) //! } //! //! // construct application with handler function and middleware. @@ -34,8 +34,8 @@ //! where //! S: for<'r> Service, Response = WebResponse, Error = Error> //! { -//! // unlike WebResponse which is already a valid http response type. the error is treated -//! // as it's onw type on the other branch of the Result type. +//! // unlike WebResponse which is already a valid http response. the error is treated as it's +//! // onw type on the other branch of the Result enum. //! //! // since the handler function at the start of example always produce error. our middleware //! // will always observe the Error type value so let's unwrap it. @@ -241,7 +241,7 @@ macro_rules! forward_blank_internal { type Error = Infallible; async fn call(&self, ctx: WebContext<'r, C, B>) -> Result { - crate::error::Internal.call(ctx).await + crate::error::ErrorStatus::internal().call(ctx).await } } }; @@ -256,7 +256,7 @@ macro_rules! forward_blank_bad_request { type Error = ::core::convert::Infallible; async fn call(&self, ctx: WebContext<'r, C, B>) -> Result { - crate::error::BadRequest.call(ctx).await + crate::error::ErrorStatus::bad_request().call(ctx).await } } }; @@ -281,8 +281,21 @@ impl<'r, C, B> Service> for Infallible { /// error type derive from http status code. /// produce minimal "StatusCode Reason" response. +#[derive(Clone)] pub struct ErrorStatus(StatusCode); +impl ErrorStatus { + #[inline] + pub const fn internal() -> Self { + Self(StatusCode::INTERNAL_SERVER_ERROR) + } + + #[inline] + pub const fn bad_request() -> Self { + Self(StatusCode::BAD_REQUEST) + } +} + impl fmt::Debug for ErrorStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.0, f) @@ -299,7 +312,13 @@ impl error::Error for ErrorStatus {} impl From for Error { fn from(e: StatusCode) -> Self { - Error::from_service(ErrorStatus(e)) + Error::from(ErrorStatus(e)) + } +} + +impl From for Error { + fn from(e: ErrorStatus) -> Self { + Error::from_service(e) } } @@ -406,36 +425,6 @@ impl<'r, C, B> Service> for StdError { } } -/// error type that produce minimal "500 InternalServerError" response. -#[derive(Debug, Clone, Copy)] -pub struct Internal; - -impl fmt::Display for Internal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Internal error") - } -} - -impl error::Error for Internal {} - -error_from_service!(Internal); -blank_error_service!(Internal, StatusCode::INTERNAL_SERVER_ERROR); - -/// error type that produce minimal "400 BadRequest" response. -#[derive(Debug)] -pub struct BadRequest; - -impl fmt::Display for BadRequest { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Bad request") - } -} - -impl error::Error for BadRequest {} - -error_from_service!(BadRequest); -blank_error_service!(BadRequest, StatusCode::BAD_REQUEST); - mod service_impl { use crate::service::object::ServiceObject; diff --git a/web/src/handler/types/query.rs b/web/src/handler/types/query.rs index 1590c198..c114c635 100644 --- a/web/src/handler/types/query.rs +++ b/web/src/handler/types/query.rs @@ -7,7 +7,7 @@ use serde::de::Deserialize; use crate::{ body::BodyStream, context::WebContext, - error::{BadRequest, Error}, + error::{Error, ErrorStatus}, handler::FromRequest, }; @@ -64,7 +64,7 @@ where #[inline] async fn from_request(ctx: &'a WebContext<'r, C, B>) -> Result { - let query = ctx.req().uri().query().ok_or(BadRequest)?; + let query = ctx.req().uri().query().ok_or(ErrorStatus::bad_request())?; Ok(LazyQuery { query: query.as_bytes(), _query: PhantomData, diff --git a/web/src/handler/types/redirect.rs b/web/src/handler/types/redirect.rs index 221493f7..93808af7 100644 --- a/web/src/handler/types/redirect.rs +++ b/web/src/handler/types/redirect.rs @@ -6,7 +6,7 @@ use xitca_http::util::service::router::{RouterGen, RouterMapErr}; use crate::{ body::ResponseBody, - error::{Error, Internal}, + error::{Error, ErrorStatus}, handler::Responder, http::{ header::{HeaderValue, LOCATION}, @@ -19,7 +19,7 @@ use crate::{ #[derive(Clone)] pub struct Redirect { status: StatusCode, - location: Result, + location: Result, } macro_rules! variants { @@ -40,7 +40,7 @@ impl Redirect { fn new(status: StatusCode, uri: impl TryInto) -> Self { Self { status, - location: uri.try_into().map_err(|_| Internal), + location: uri.try_into().map_err(|_| ErrorStatus::internal()), } } } @@ -55,7 +55,7 @@ impl<'r, C, B> Responder> for Redirect { } fn map(self, res: Self::Response) -> Result { - let location = self.location.map_err(|_| Internal)?; + let location = self.location.map_err(|_| ErrorStatus::internal())?; let map = (self.status, (LOCATION, location)); Responder::>::map(map, res) } diff --git a/web/src/handler/types/websocket.rs b/web/src/handler/types/websocket.rs index 92ef2a93..23cf261b 100644 --- a/web/src/handler/types/websocket.rs +++ b/web/src/handler/types/websocket.rs @@ -22,7 +22,7 @@ use crate::{ body::{BodyStream, RequestBody, ResponseBody}, bytes::Bytes, context::WebContext, - error::{Error, Internal}, + error::{Error, ErrorStatus}, handler::{FromRequest, Responder}, http::{ header::{CONNECTION, SEC_WEBSOCKET_VERSION, UPGRADE}, @@ -148,7 +148,7 @@ impl<'r, C, B> Service> for HandshakeError { HandshakeError::NoVersionHeader => HeaderNotFound(SEC_WEBSOCKET_VERSION), HandshakeError::NoWebsocketUpgrade => HeaderNotFound(UPGRADE), // TODO: refine error mapping of the remaining branches. - _ => return Internal.call(ctx).await, + _ => return ErrorStatus::internal().call(ctx).await, }; e.call(ctx).await diff --git a/web/src/service/file.rs b/web/src/service/file.rs index 2092fba8..5cce2637 100644 --- a/web/src/service/file.rs +++ b/web/src/service/file.rs @@ -72,7 +72,7 @@ mod service { use crate::{ body::ResponseBody, context::WebContext, - error::{BadRequest, Error, Internal, MatchError, MethodNotAllowed, RouterError}, + error::{Error, ErrorStatus, MatchError, MethodNotAllowed, RouterError}, http::{Method, StatusCode, WebResponse}, service::Service, }; @@ -96,8 +96,8 @@ mod service { ServeError::MethodNotAllowed => { RouterError::NotAllowed(MethodNotAllowed(vec![Method::GET, Method::HEAD])) } - ServeError::Io(_) => RouterError::Service(Error::from_service(Internal)), - _ => RouterError::Service(Error::from_service(BadRequest)), + ServeError::Io(_) => RouterError::Service(Error::from(ErrorStatus::internal())), + _ => RouterError::Service(Error::from(ErrorStatus::bad_request())), }), } }