Skip to content

错误处理:系统返回 Result

从 Bevy 0.15 起,系统函数可以返回 Result<(), BevyError>(或简写为 Result)。如果系统返回 Err,Bevy 会调用当前配置的错误处理器(error handler)来处理它。

rust
use bevy::prelude::*;

#[derive(Resource)]
struct Health(f32);

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(Health(100.0))
        .add_systems(Startup, setup)
        .add_systems(Update, drain_health)
        .run();
}

fn setup() {
    info!("可恢复系统示例:Health 每帧 -1,归零时报错");
}

fn drain_health(mut health: ResMut<Health>, time: Res<Time>) -> Result {
    health.0 -= time.delta_secs() * 10.0;
    if health.0 <= 0.0 {
        health.0 = 0.0;
        return Err(BevyError::from(
            "Health 耗尽——系统返回 Err,由默认错误处理器记录",
        ));
    }
    Ok(())
}

Listing 33-3:系统返回 Result——Err 由默认错误处理器记录

默认的错误处理器是 panic——在开发期直接 panic,方便定位问题。你可以切换到更温和的方式:

rust
use bevy::prelude::*;

App::new()
    .add_plugins(DefaultPlugins)
    // 全局切换为 warn 级别日志,不 panic
    .set_error_handler(bevy_ecs::error::warn)
    .run();

Bevy 内置的错误处理器有:

函数行为
panic直接 panic(默认)
errorerror! 记录日志
warnwarn! 记录日志
infoinfo! 记录日志
debugdebug! 记录日志
tracetrace! 记录日志
ignore静默忽略

也可以自定义:注册一个 fn(BevyError, ErrorContext) 函数到 DefaultErrorHandler 资源。ErrorContext 提供了出错系统的名称等上下文信息,可以按系统名做差异化处理。

BevyError

BevyError 是一个类型擦除的错误类型,任何实现了 std::error::Error + Send + Sync + 'static 的类型都可以通过 From 自动转换为 BevyError。常见用法:

rust
fn my_system() -> Result {
    let value = some_operation()
        .ok_or_else(|| BevyError::from("操作失败"))?;
    Ok(())
}

? 运算符会自动把标准库错误(io::Error 等)转换为 BevyError,无需手动包装。

Commands 中的错误处理

Commands 也可以返回错误。用 HandleError::handle_error_with 方法可以为单个命令指定错误处理器,覆盖全局设置:

rust
commands.queue(some_fallible_command).handle_error_with(bevy_ecs::error::warn);