fix B0003 example and update logs (#11162)

# Objective

- Example in error B0003 is not failing anymore after #9822

## Solution

- Update the example code so that is always fail
- Also update logs and instructions on how to debug as it's easier now

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
François 2024-01-10 22:40:24 +01:00 committed by GitHub
parent a657478675
commit d4ffd4ff28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,98 +11,52 @@ fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, despawning)
.add_systems(Update, use_entity.after(despawning))
.add_systems(Update, (use_0_and_despawn_1, use_1_and_despawn_0))
.run();
}
#[derive(Resource)]
struct MyEntity(Entity);
struct MyEntities(Entity, Entity);
#[derive(Component)]
struct Hello;
fn setup(mut commands: Commands) {
let entity = commands.spawn_empty().id();
commands.insert_resource(MyEntity(entity));
let entity1 = commands.spawn_empty().id();
let entity2 = commands.spawn_empty().id();
commands.insert_resource(MyEntities(entity1, entity2));
}
fn despawning(mut commands: Commands, entity: Option<Res<MyEntity>>) {
if let Some(my_entity) = entity {
commands.entity(my_entity.0).despawn();
commands.remove_resource::<MyEntity>();
}
fn use_0_and_despawn_1(mut commands: Commands, my_entities: Res<MyEntities>) {
commands.entity(my_entities.0).insert(Hello);
commands.entity(my_entities.1).despawn();
}
fn use_entity(mut commands: Commands, entity: Option<Res<MyEntity>>) {
if let Some(my_entity) = entity {
commands.entity(my_entity.0).insert(Hello);
}
fn use_1_and_despawn_0(mut commands: Commands, my_entities: Res<MyEntities>) {
commands.entity(my_entities.1).insert(Hello);
commands.entity(my_entities.0).despawn();
}
```
This will panic, as system `use_entity` is executed after system `despawning`. Without the system ordering specified here, the ordering would be random and this code would panic half the time.
This will panic, as the system that is executed first will despawn the entity used by the second.
The default panic message is telling you the entity id (`1v0`) and the command that failed (adding a component `Hello`):
The default panic message is telling you which entity doesn't exist (`2v0` in the example log just below), the command that failed (adding a component `Hello`) and the system from which it originated (`use_1_and_despawn_0`):
```text
thread 'main' panicked at 'error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 1v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:934:13
thread 'main' panicked at /bevy/crates/bevy_ecs/src/system/commands/mod.rs:1097:13:
error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 2v0 because it doesn't exist in this World.
Encountered a panic when applying buffers for system `use_entity_after_despawn::use_1_and_despawn_0`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
```
But you don't know which system tried to add a component, and which system despawned the entity.
To get the system that created the command that panics, you can enable the `trace` feature of Bevy. This will add a panic handler that will print more information:
To get the system that created the despawn command, you can enable DEBUG logs for crate `bevy_ecs`, for example by setting the environment variable `RUST_LOG=bevy_ecs=debug` or by configuring the `LogPlugin`. This will log:
```text
0: bevy_ecs::system::commands::system_commands
with name="use_entity_after_despawn::use_entity"
at crates/bevy_ecs/src/system/commands/mod.rs:117
1: bevy_ecs::world::schedule
with name=Update
at crates/bevy_ecs/src/world/mod.rs:1755
2: bevy_ecs::schedule::executor::single_threaded::system
with name="bevy_app::main_schedule::Main::run_main"
at crates/bevy_ecs/src/schedule/executor/single_threaded.rs:98
3: bevy_ecs::world::schedule
with name=Main
at crates/bevy_ecs/src/world/mod.rs:1755
4: bevy_app::app::main app
at crates/bevy_app/src/app.rs:249
5: bevy_app::app::update
at crates/bevy_app/src/app.rs:246
6: bevy_winit::winit event_handler
at crates/bevy_winit/src/lib.rs:338
7: bevy_app::app::bevy_app
at crates/bevy_app/src/app.rs:290
thread 'main' panicked at 'error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 1v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:934:13
DEBUG system_commands{name="use_entity_after_despawn::use_0_and_despawn_1"}: bevy_ecs::world::entity_ref: Despawning entity 2v0
thread 'main' panicked at /bevy/crates/bevy_ecs/src/system/commands/mod.rs:1097:13:
error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 2v0 because it doesn't exist in this World.
Encountered a panic when applying buffers for system `use_entity_after_despawn::use_1_and_despawn_0`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
```
From the first two lines, you now know that it panics while executing a command from the system `use_entity`.
To get the system that created the despawn command, you can enable DEBUG logs for crate `bevy_ecs`, for example by setting the environment variable `RUST_LOG=bevy_ecs=debug`. This will log:
```text
DEBUG schedule{name=Main}:system{name="bevy_app::main_schedule::Main::run_main"}:schedule{name=Update}:system_commands{name="use_entity_after_despawn::despawning"}: bevy_ecs::world::entity_ref: Despawning entity 1v0
thread 'main' panicked at 'error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 1v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:934:13
```
From the first line, you know the entity `1v0` was despawned when executing a command from system `despawning`. In a real case, you could have many log lines, you will need to search for the exact entity from the panic message.
Combining those two, you should get enough information to understand why this panic is happening and how to fix it:
```text
DEBUG schedule{name=Main}:system{name="bevy_app::main_schedule::Main::run_main"}:schedule{name=Update}:system_commands{name="use_entity_after_despawn::despawning"}: bevy_ecs::world::entity_ref: Despawning entity 1v0
0: bevy_ecs::system::commands::system_commands
with name="use_entity_after_despawn::use_entity"
at crates/bevy_ecs/src/system/commands/mod.rs:117
1: bevy_ecs::world::schedule
with name=Update
at crates/bevy_ecs/src/world/mod.rs:1755
2: bevy_ecs::schedule::executor::single_threaded::system
with name="bevy_app::main_schedule::Main::run_main"
at crates/bevy_ecs/src/schedule/executor/single_threaded.rs:98
3: bevy_ecs::world::schedule
with name=Main
at crates/bevy_ecs/src/world/mod.rs:1755
thread 'main' panicked at 'error[B0003]: Could not insert a bundle (of type `use_entity_after_despawn::Hello`) for entity 1v0 because it doesn't exist in this World.', /bevy/crates/bevy_ecs/src/system/commands/mod.rs:934:13
```
From the first line, you know the entity `2v0` was despawned when executing a command from system `use_0_and_despawn_1`. In a real case, you could have many log lines, you will need to search for the exact entity from the panic message.