carapax/core/error/
mod.rs1use std::{future::Future, marker::PhantomData};
2
3use crate::core::{
4 convert::TryFromInput,
5 handler::{Handler, HandlerError, HandlerInput, HandlerResult, IntoHandlerResult},
6};
7
8#[cfg(test)]
9mod tests;
10
11pub struct ErrorDecorator<E, H, HI> {
13 error_handler: E,
14 handler: H,
15 handler_input: PhantomData<HI>,
16}
17
18impl<E, H, HI> ErrorDecorator<E, H, HI> {
19 pub fn new(error_handler: E, handler: H) -> Self {
26 Self {
27 error_handler,
28 handler,
29 handler_input: PhantomData,
30 }
31 }
32}
33
34impl<E, H, HI> Clone for ErrorDecorator<E, H, HI>
35where
36 E: Clone,
37 H: Clone,
38{
39 fn clone(&self) -> Self {
40 Self {
41 error_handler: self.error_handler.clone(),
42 handler: self.handler.clone(),
43 handler_input: PhantomData,
44 }
45 }
46}
47
48impl<E, H, HI> Handler<HandlerInput> for ErrorDecorator<E, H, HI>
49where
50 E: ErrorHandler + Clone + Sync + 'static,
51 H: Handler<HI> + Sync + 'static,
52 HI: TryFromInput + Sync,
53 HI::Error: 'static,
54 H::Output: IntoHandlerResult,
55{
56 type Output = HandlerResult;
57
58 async fn handle(&self, input: HandlerInput) -> Self::Output {
59 let future = HI::try_from_input(input);
60 match future.await {
61 Ok(Some(input)) => match self.handler.handle(input).await.into_result() {
62 Err(err) => Err(self.error_handler.handle(err).await),
63 result => result,
64 },
65 Ok(None) => Ok(()),
66 Err(err) => Err(self.error_handler.handle(HandlerError::new(err)).await),
67 }
68 }
69}
70
71pub trait ErrorHandler: Send {
73 fn handle(&self, err: HandlerError) -> impl Future<Output = HandlerError> + Send;
79}
80
81impl<H, F> ErrorHandler for H
82where
83 H: Fn(HandlerError) -> F + Send + Sync,
84 F: Future<Output = HandlerError> + Send,
85{
86 async fn handle(&self, err: HandlerError) -> HandlerError {
87 (self)(err).await
88 }
89}
90
91pub trait ErrorExt<E, HI>: Sized {
93 fn on_error(self, error_handler: E) -> ErrorDecorator<E, Self, HI> {
101 ErrorDecorator::new(error_handler, self)
102 }
103}
104
105impl<E, H, HI> ErrorExt<E, HI> for H
106where
107 H: Handler<HI>,
108 HI: TryFromInput,
109{
110}