viz_core/handler/
catch_error.rs1use std::marker::PhantomData;
2
3use crate::{Handler, IntoResponse, Response, Result};
4
5#[derive(Debug)]
7pub struct CatchError<H, F, E, R> {
8 h: H,
9 f: F,
10 _marker: PhantomData<fn(E) -> R>,
11}
12
13impl<H, F, E, R> Clone for CatchError<H, F, E, R>
14where
15 H: Clone,
16 F: Clone,
17{
18 fn clone(&self) -> Self {
19 Self {
20 h: self.h.clone(),
21 f: self.f.clone(),
22 _marker: PhantomData,
23 }
24 }
25}
26
27impl<H, F, E, R> CatchError<H, F, E, R> {
28 #[inline]
30 pub fn new(h: H, f: F) -> Self {
31 Self {
32 h,
33 f,
34 _marker: PhantomData,
35 }
36 }
37}
38
39#[crate::async_trait]
40impl<H, I, O, F, E, R> Handler<I> for CatchError<H, F, E, R>
41where
42 I: Send + 'static,
43 H: Handler<I, Output = Result<O>>,
44 O: IntoResponse + Send,
45 E: std::error::Error + Send + 'static,
46 F: Handler<E, Output = R>,
47 R: IntoResponse + 'static,
48{
49 type Output = Result<Response>;
50
51 async fn call(&self, i: I) -> Self::Output {
52 match self.h.call(i).await {
53 Ok(r) => Ok(r.into_response()),
54 Err(e) => Ok(self.f.call(e.downcast::<E>()?).await.into_response()),
55 }
56 }
57}