Skip to content

Commit

Permalink
B0003: Print caller (#14556)
Browse files Browse the repository at this point in the history
# Objective

B0003 indicates that you tried to act upon a nonexistant entity, but
does not mention where the error occured:
```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

## Solution

Include caller location:

```
2024-07-31T15:46:25.954840Z  WARN bevy_ecs::world: error[B0003]: src/main.rs:18:11: Could not despawn entity Entity { index: 4294967295, generation: 1 } because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
```

Open question: What should the exact message format be?

## Testing

None, this doesn't change any logic.
  • Loading branch information
SpecificProtagonist authored Aug 1, 2024
1 parent d5ccb09 commit 0685d2d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
19 changes: 12 additions & 7 deletions crates/bevy_ecs/src/system/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mod parallel_scope;

#[cfg(feature = "track_change_detection")]
use core::panic::Location;

use super::{Deferred, IntoObserverSystem, IntoSystem, RegisterSystem, Resource};
Expand Down Expand Up @@ -963,14 +962,16 @@ impl EntityCommands<'_> {
///
/// - [`ComponentId`] must be from the same world as `self`.
/// - `T` must have the same layout as the one passed during `component_id` creation.
#[track_caller]
pub unsafe fn insert_by_id<T: Send + 'static>(
&mut self,
component_id: ComponentId,
value: T,
) -> &mut Self {
let caller = Location::caller();
// SAFETY: same invariants as parent call
self.add(unsafe {insert_by_id(component_id, value, move |entity| {
panic!("error[B0003]: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/#b0003", std::any::type_name::<T>());
panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/#b0003", std::any::type_name::<T>());
})});
self
}
Expand Down Expand Up @@ -1125,8 +1126,9 @@ impl EntityCommands<'_> {
/// }
/// # bevy_ecs::system::assert_is_system(remove_character_system);
/// ```
#[track_caller]
pub fn despawn(&mut self) {
self.add(despawn);
self.add(despawn());
}

/// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
Expand Down Expand Up @@ -1300,14 +1302,17 @@ where
///
/// This won't clean up external references to the entity (such as parent-child relationships
/// if you're using `bevy_hierarchy`), which may leave the world in an invalid state.
fn despawn(entity: Entity, world: &mut World) {
world.despawn(entity);
#[track_caller]
fn despawn() -> impl EntityCommand {
let caller = Location::caller();
move |entity: Entity, world: &mut World| {
world.despawn_with_caller(entity, caller);
}
}

/// An [`EntityCommand`] that adds the components in a [`Bundle`] to an entity.
#[track_caller]
fn insert<T: Bundle>(bundle: T) -> impl EntityCommand {
#[cfg(feature = "track_change_detection")]
let caller = core::panic::Location::caller();
move |entity: Entity, world: &mut World| {
if let Some(mut entity) = world.get_entity_mut(entity) {
Expand All @@ -1317,7 +1322,7 @@ fn insert<T: Bundle>(bundle: T) -> impl EntityCommand {
caller,
);
} else {
panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::<T>(), entity);
panic!("error[B0003]: {caller}: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::<T>(), entity);
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use std::{

#[cfg(feature = "track_change_detection")]
use bevy_ptr::UnsafeCellDeref;
#[cfg(feature = "track_change_detection")]

use core::panic::Location;

use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};
Expand Down Expand Up @@ -1121,14 +1121,24 @@ impl World {
/// assert!(world.get_entity(entity).is_none());
/// assert!(world.get::<Position>(entity).is_none());
/// ```
#[track_caller]
#[inline]
pub fn despawn(&mut self, entity: Entity) -> bool {
self.despawn_with_caller(entity, Location::caller())
}

#[inline]
pub(crate) fn despawn_with_caller(
&mut self,
entity: Entity,
caller: &'static Location,
) -> bool {
self.flush();
if let Some(entity) = self.get_entity_mut(entity) {
entity.despawn();
true
} else {
warn!("error[B0003]: Could not despawn entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", entity);
warn!("error[B0003]: {caller}: Could not despawn entity {:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", entity);
false
}
}
Expand Down

0 comments on commit 0685d2d

Please sign in to comment.