Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce error types. #922

Merged
merged 2 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion web/CHANGES.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion web/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
65 changes: 27 additions & 38 deletions web/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -34,8 +34,8 @@
//! where
//! S: for<'r> Service<WebContext<'r>, 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.
Expand Down Expand Up @@ -241,7 +241,7 @@ macro_rules! forward_blank_internal {
type Error = Infallible;

async fn call(&self, ctx: WebContext<'r, C, B>) -> Result<Self::Response, Self::Error> {
crate::error::Internal.call(ctx).await
crate::error::ErrorStatus::internal().call(ctx).await
}
}
};
Expand All @@ -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<Self::Response, Self::Error> {
crate::error::BadRequest.call(ctx).await
crate::error::ErrorStatus::bad_request().call(ctx).await
}
}
};
Expand All @@ -281,8 +281,21 @@ impl<'r, C, B> Service<WebContext<'r, C, B>> 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)
Expand All @@ -299,7 +312,13 @@ impl error::Error for ErrorStatus {}

impl<C> From<StatusCode> for Error<C> {
fn from(e: StatusCode) -> Self {
Error::from_service(ErrorStatus(e))
Error::from(ErrorStatus(e))
}
}

impl<C> From<ErrorStatus> for Error<C> {
fn from(e: ErrorStatus) -> Self {
Error::from_service(e)
}
}

Expand Down Expand Up @@ -406,36 +425,6 @@ impl<'r, C, B> Service<WebContext<'r, C, B>> 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;

Expand Down
4 changes: 2 additions & 2 deletions web/src/handler/types/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::de::Deserialize;
use crate::{
body::BodyStream,
context::WebContext,
error::{BadRequest, Error},
error::{Error, ErrorStatus},
handler::FromRequest,
};

Expand Down Expand Up @@ -64,7 +64,7 @@ where

#[inline]
async fn from_request(ctx: &'a WebContext<'r, C, B>) -> Result<Self, Self::Error> {
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,
Expand Down
8 changes: 4 additions & 4 deletions web/src/handler/types/redirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -19,7 +19,7 @@ use crate::{
#[derive(Clone)]
pub struct Redirect {
status: StatusCode,
location: Result<HeaderValue, Internal>,
location: Result<HeaderValue, ErrorStatus>,
}

macro_rules! variants {
Expand All @@ -40,7 +40,7 @@ impl Redirect {
fn new(status: StatusCode, uri: impl TryInto<HeaderValue>) -> Self {
Self {
status,
location: uri.try_into().map_err(|_| Internal),
location: uri.try_into().map_err(|_| ErrorStatus::internal()),
}
}
}
Expand All @@ -55,7 +55,7 @@ impl<'r, C, B> Responder<WebContext<'r, C, B>> for Redirect {
}

fn map(self, res: Self::Response) -> Result<Self::Response, Self::Error> {
let location = self.location.map_err(|_| Internal)?;
let location = self.location.map_err(|_| ErrorStatus::internal())?;
let map = (self.status, (LOCATION, location));
Responder::<WebContext<'r, C, B>>::map(map, res)
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/handler/types/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -148,7 +148,7 @@ impl<'r, C, B> Service<WebContext<'r, C, B>> 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
Expand Down
6 changes: 3 additions & 3 deletions web/src/service/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -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())),
}),
}
}
Expand Down
Loading