恐慌钩子
2026/1/2大约 1 分钟hyperlanewebrustconfigtask_panic
提示
hyperlane 框架内部会对 panic 进行捕获,用户可通过钩子进行设置(框架默认仅捕获异常不处理异常), 需要注意的是,执行 panic 之前,框架会重置 aborted 状态, 支持多次注册,按照注册顺序进行执行,如果任何阶段返回了 Status::Reject,则后续注册的 task_panic 将不会执行。
原生写法
struct TaskPanicHook {
response_body: String,
content_type: String,
}
impl ServerHook for TaskPanicHook {
async fn new(_: &mut Stream, ctx: &mut Context) -> Self {
let error: PanicData = ctx.try_get_task_panic_data().unwrap_or_default();
let response_body: String = error.to_string();
let content_type: String = ContentType::format_content_type_with_charset(TEXT_PLAIN, UTF8);
Self {
response_body,
content_type,
}
}
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
let data: Vec<u8> = ctx
.get_mut_response()
.set_version(HttpVersion::Http1_1)
.set_status_code(500)
.clear_headers()
.set_header(SERVER, HYPERLANE)
.set_header(CONTENT_TYPE, &self.content_type)
.set_body(&self.response_body)
.build();
if stream.try_send(data).await.is_err() {
stream.set_closed(true);
return Status::Reject;
}
Status::Continue
}
}
server.task_panic::<TaskPanicHook>();属性宏写法
use hyperlane::*;
use hyperlane_macros::*;
#[task_panic]
struct TaskPanicHook;
impl ServerHook for TaskPanicHook {
async fn new(_: &mut Stream, ctx: &mut Context) -> Self {
Self
}
#[epilogue_macros(response_body("task_panic"), send)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
let error: PanicData = ctx.try_get_task_panic_data().unwrap_or_default();
Status::Continue
}
}使用属性宏获取恐慌数据
提示
可以使用 #[try_get_task_panic_data] 或 #[task_panic_data] 属性宏提取恐慌数据。
安全获取恐慌数据(返回 Option)
#[try_get_task_panic_data(panic_data)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
if let Some(data) = panic_data {
// use data
}
Status::Continue
}不安全获取恐慌数据(获取失败会 Panic)
#[task_panic_data(panic_data)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// panic_data is available directly
Status::Continue
}指定执行顺序
提示
如果不指定 order 参数,钩子的优先级高于指定了 order 的钩子。
#[task_panic(1)]
struct TaskPanicHook1;
#[task_panic("2")]
struct TaskPanicHook2;