rust - 如何在捕获时向panick_info添加更多上下文?

标签 rust panic

在我的项目中,我有一个 panic 钩子(Hook),当发生一些计划外的解包时,它会发送一个 HTTP 请求来报告问题。我正在执行某个函数 100 次,我想以某种方式知道何时发生 panic ,是哪一次执行,以防 panic 发生在函数内部。是否可以以某种方式将字符串添加到拦截的panic_info展开中,或者人们如何处理这个问题?

我正在考虑使用catch_unwind,修改捕获的错误并恢复展开,但错误是不透明类型的,所以我看不到向其添加内容的方法。我看到panic_info有有效负载,是否可以以某种方式添加到它?

我想避免使用一些全局互斥体,然后我可以在捕获展开时对其进行修改

最佳答案

一个简单的选择是仅使用 expect() 而不是 unwrap() 并使用信息性错误消息。

另一种方法是使用自定义 panic 类型并尝试向下转换它,例如:

use std::any::Any;
use std::panic::{self, panic_any, UnwindSafe};

// The custom panic payload.
// Must be `'static + Any + Send` for `panic_any()`.
pub struct MyPanicInfo {
    pub description: String,
}

trait OptionExt {
    type Inner;
    fn unwrap_with<F: FnOnce() -> MyPanicInfo>(self, f: F) -> Self::Inner;
}
impl<T> OptionExt for Option<T> {
    type Inner = T;
    fn unwrap_with<F: FnOnce() -> MyPanicInfo>(self, f: F) -> Self::Inner {
        match self {
            Some(v) => v,
            None => panic_any(f()),
        }
    }
}

trait ResultExt {
    type Ok;
    type Err;
    fn unwrap_with<F: FnOnce(Self::Err) -> MyPanicInfo>(self, f: F) -> Self::Ok;
}
impl<T, E> ResultExt for Result<T, E> {
    type Ok = T;
    type Err = E;
    fn unwrap_with<F: FnOnce(<Self as ResultExt>::Err) -> MyPanicInfo>(
        self,
        f: F,
    ) -> <Self as ResultExt>::Ok {
        match self {
            Ok(v) => v,
            Err(e) => panic_any(f(e)),
        }
    }
}

pub enum PanicPayload {
    MyPanicInfo(Box<MyPanicInfo>),
    Unknown(Box<dyn Any + Send>),
}
pub fn my_catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R, PanicPayload> {
    panic::catch_unwind(f).map_err(|payload| match payload.downcast() {
        Ok(my_panic_info) => PanicPayload::MyPanicInfo(my_panic_info),
        Err(unknown_payload) => PanicPayload::Unknown(unknown_payload),
    })
}

然后使用类似于 option.unwrap_with(|| MyPanicInfo { description: "abc".to_owned() }) 的内容。

关于rust - 如何在捕获时向panick_info添加更多上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71065025/

相关文章:

rust - 在Rust中使用单个增变器进行无锁数据共享

for-loop - 如果 panic 发生,恢复并继续 for 循环 Golang

debugging - 了解内核oops错误代码

string - Rust 是否提供了一种直接从字节 (u8) 数组中的 ASCII 数据解析整数的方法?

for-loop - 如何在 vector 的元素上运行 for 循环并更改 for 循环内部和 for 循环外部的向量?

rust - 从闭包中返回时的RefMut生命周期错误

rust - 实现 Deref 特征时无法为生命周期参数推断出合适的生命周期

c++ - Esp32紧急每隔一个HTTP发布请求

使用 panic CODA 的 Python 缩进问题

dictionary - 将值插入 map 时出现 panic /错误