You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让BevyError使用内部错误的原始回溯信息?

如何让BevyError使用内部错误的原始回溯信息?

我完全懂你的 frustration!当用BevyError包装自定义错误时,它默认抓的是转换那一刻的回溯(比如你在foo_system里用?的地方),而不是真正出问题的bar()函数,这排查问题时真的很闹心。好在有几个可行的办法解决这个问题,我给你慢慢说:

方案一:把原始回溯直接包含在错误消息里(最简单)

既然BevyError会打印内部错误的描述信息,那我们直接把自定义错误的回溯塞进错误消息里就行。修改你的InnerError定义,让它的#[error]宏包含backtrace字段:

#[derive(Debug, thiserror::Error)]
#[error("oh no!\n原始错误回溯:\n{backtrace}")]
struct InnerError {
    backtrace: Backtrace,
}

这样当BevyError包装这个错误并打印时,错误消息里就会直接显示bar()的调用栈——完全不需要改Bevy的逻辑,只需要调整自己的错误类型。

方案二:自定义Bevy的错误处理逻辑(更灵活)

如果你不想污染错误消息,也可以自己接管Bevy的错误处理,手动遍历错误链,提取并打印原始错误的回溯。在main函数里用set_error_handler替换默认的错误处理:

fn main() {
    let mut app: App = App::new();
    app.add_systems(Startup, foo_system)
        .set_error_handler(|err: BevyError| {
            eprintln!("系统出错: {}", err);
            
            // 遍历错误链,找到原始错误的回溯
            let mut current_err = &err as &dyn std::error::Error;
            while let Some(source) = current_err.source() {
                if let Some(backtrace) = core::error::request_ref::<Backtrace>(source) {
                    eprintln!("\n原始错误的调用栈:\n{}", backtrace);
                }
                current_err = source;
            }
        });
    app.run();
}

这样Bevy会用你写的逻辑处理错误,既能保留Bevy默认的错误提示,又能显示你真正关心的bar()位置的回溯。

为什么默认的From实现不行?

顺便给你理清楚根源:BevyError的全局From<E>实现会在转换错误时调用Backtrace::capture(),抓的是当前调用栈(也就是你用?或者BevyError::from(err)的那一行),而不是原始错误发生时的栈。而且BevyError的内部字段是私有的,我们没法直接替换它的回溯——所以上面两个方案是最稳妥的,不需要碰Bevy的内部实现。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:53:01