错误处理:系统返回 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(默认) |
error | 用 error! 记录日志 |
warn | 用 warn! 记录日志 |
info | 用 info! 记录日志 |
debug | 用 debug! 记录日志 |
trace | 用 trace! 记录日志 |
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);