use std::panic::AssertUnwindSafe;

use futures::FutureExt;
use salvo::{Depot, FlowCtrl, Handler, Request, Response, Writer, async_trait};

use crate::status::api_err::ApiErr;

#[derive(Default)]
pub struct Catch;

impl Catch {
    #[inline]
    pub fn new() -> Self {
        Catch {}
    }
}

#[async_trait]
impl Handler for Catch {
    async fn handle(&self, req: &mut Request, depot: &mut Depot, resp: &mut Response, ctrl: &mut FlowCtrl) {
        let ret = AssertUnwindSafe(ctrl.call_next(req, depot, resp)).catch_unwind().await;
        if ret.is_err() {
            ApiErr::Panic.write(req, depot, resp).await;
        }
    }
}
