Skip to content

Commit

Permalink
feat(response): async error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuwn committed Apr 6, 2023
1 parent 97968c5 commit fc21a67
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
19 changes: 16 additions & 3 deletions src/handler/response/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,23 @@
// Copyright (C) 2022-2022 Fuwn <contact@fuwn.me>
// SPDX-License-Identifier: GPL-3.0-only

use async_trait::async_trait;

use crate::{context::ErrorContext, Response};

#[allow(clippy::module_name_repetitions)]
pub trait ErrorResponse: FnMut(ErrorContext) -> Response + Send + Sync {}
#[async_trait]
pub trait ErrorResponse: Send + Sync {
async fn call(&mut self, context: ErrorContext) -> Response;
}

impl<T> ErrorResponse for T where T: FnMut(ErrorContext) -> Response + Send + Sync
{}
#[async_trait]
impl<T, F> ErrorResponse for T
where
T: FnMut(ErrorContext) -> F + Send + Sync,
F: std::future::Future<Output = Response> + Send + 'static,
{
async fn call(&mut self, context: ErrorContext) -> Response {
(*self)(context).await
}
}
4 changes: 1 addition & 3 deletions src/handler/response/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
// Copyright (C) 2022-2022 Fuwn <contact@fuwn.me>
// SPDX-License-Identifier: GPL-3.0-only

use std::future::Future;

use async_trait::async_trait;

use crate::{context::RouteContext, Response};
Expand All @@ -32,7 +30,7 @@ pub trait RouteResponse: Send + Sync {
impl<T, F> RouteResponse for T
where
T: FnMut(RouteContext<'_>) -> F + Send + Sync,
F: Future<Output = Response> + Send + 'static,
F: std::future::Future<Output = Response> + Send + 'static,
{
async fn call(&mut self, context: RouteContext<'_>) -> Response {
(*self)(context).await
Expand Down
40 changes: 26 additions & 14 deletions src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ macro_rules! or_error {
#[derive(Clone)]
pub struct Router {
routes: matchit::Router<Arc<AsyncMutex<Box<dyn RouteResponse>>>>,
error_handler: Arc<Mutex<Box<dyn ErrorResponse<Output = Response>>>>,
error_handler: Arc<AsyncMutex<Box<dyn ErrorResponse>>>,
private_key_file_name: String,
ca_file_name: String,
headers: Arc<Mutex<Vec<Box<dyn Partial<Output = String>>>>>,
Expand Down Expand Up @@ -190,11 +190,17 @@ impl Router {
/// windmark::success!("You have encountered an error!")
/// });
/// ```
pub fn set_error_handler(
pub fn set_error_handler<R>(
&mut self,
handler: impl ErrorResponse + 'static,
) -> &mut Self {
self.error_handler = Arc::new(Mutex::new(Box::new(handler)));
mut handler: impl FnMut(ErrorContext) -> R + Send + Sync + 'static,
) -> &mut Self
where
R: IntoFuture<Output = Response> + Send + 'static,
<R as IntoFuture>::IntoFuture: Send,
{
self.error_handler = Arc::new(AsyncMutex::new(Box::new(move |context| {
handler(context).into_future()
})));

self
}
Expand Down Expand Up @@ -398,11 +404,15 @@ impl Router {

handler.await
} else {
(*self.error_handler).lock().unwrap()(ErrorContext::new(
stream.get_ref().peer_addr(),
url.clone(),
peer_certificate,
))
(*self.error_handler)
.lock()
.await
.call(ErrorContext::new(
stream.get_ref().peer_addr(),
url.clone(),
peer_certificate,
))
.await
};

for module in &mut *self.async_modules.lock().await {
Expand Down Expand Up @@ -855,10 +865,12 @@ impl Default for Router {
fn default() -> Self {
Self {
routes: matchit::Router::new(),
error_handler: Arc::new(Mutex::new(Box::new(|_| {
Response::not_found(
"This capsule has not implemented an error handler...",
)
error_handler: Arc::new(AsyncMutex::new(Box::new(|_| {
async {
Response::not_found(
"This capsule has not implemented an error handler...",
)
}
}))),
private_key_file_name: String::new(),
ca_file_name: String::new(),
Expand Down

0 comments on commit fc21a67

Please sign in to comment.