1use crate::WebError;
2use anyhow::Result;
3use futures_util::FutureExt;
4use std::future::Future;
5use std::panic::AssertUnwindSafe;
6
7pub async fn catch_panic<F, T>(future: F) -> Result<T>
8where
9 F: Future<Output = T>,
10{
11 AssertUnwindSafe(future)
12 .catch_unwind()
13 .await
14 .map_err(|payload| WebError::panic(panic_message(payload)).into())
15}
16
17fn panic_message(payload: Box<dyn std::any::Any + Send>) -> String {
18 if let Some(message) = payload.downcast_ref::<String>() {
19 return format!("请求执行发生 panic:{message}");
20 }
21 if let Some(message) = payload.downcast_ref::<&str>() {
22 return format!("请求执行发生 panic:{message}");
23 }
24 "请求执行发生未知 panic".to_string()
25}