B0003: Print caller (#14556)
# 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.
			
			
This commit is contained in:
		
							parent
							
								
									d5ccb096b5
								
							
						
					
					
						commit
						0685d2da4d
					
				| @ -1,6 +1,5 @@ | |||||||
| mod parallel_scope; | mod parallel_scope; | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "track_change_detection")] |  | ||||||
| use core::panic::Location; | use core::panic::Location; | ||||||
| 
 | 
 | ||||||
| use super::{Deferred, IntoObserverSystem, IntoSystem, RegisterSystem, Resource}; | use super::{Deferred, IntoObserverSystem, IntoSystem, RegisterSystem, Resource}; | ||||||
| @ -963,14 +962,16 @@ impl EntityCommands<'_> { | |||||||
|     ///
 |     ///
 | ||||||
|     /// - [`ComponentId`] must be from the same world as `self`.
 |     /// - [`ComponentId`] must be from the same world as `self`.
 | ||||||
|     /// - `T` must have the same layout as the one passed during `component_id` creation.
 |     /// - `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>( |     pub unsafe fn insert_by_id<T: Send + 'static>( | ||||||
|         &mut self, |         &mut self, | ||||||
|         component_id: ComponentId, |         component_id: ComponentId, | ||||||
|         value: T, |         value: T, | ||||||
|     ) -> &mut Self { |     ) -> &mut Self { | ||||||
|  |         let caller = Location::caller(); | ||||||
|         // SAFETY: same invariants as parent call
 |         // SAFETY: same invariants as parent call
 | ||||||
|         self.add(unsafe {insert_by_id(component_id, value, move |entity| { |         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 |         self | ||||||
|     } |     } | ||||||
| @ -1125,8 +1126,9 @@ impl EntityCommands<'_> { | |||||||
|     /// }
 |     /// }
 | ||||||
|     /// # bevy_ecs::system::assert_is_system(remove_character_system);
 |     /// # bevy_ecs::system::assert_is_system(remove_character_system);
 | ||||||
|     /// ```
 |     /// ```
 | ||||||
|  |     #[track_caller] | ||||||
|     pub fn despawn(&mut self) { |     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`].
 |     /// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
 | ||||||
| @ -1300,14 +1302,17 @@ where | |||||||
| ///
 | ///
 | ||||||
| /// This won't clean up external references to the entity (such as parent-child relationships
 | /// 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.
 | /// if you're using `bevy_hierarchy`), which may leave the world in an invalid state.
 | ||||||
| fn despawn(entity: Entity, world: &mut World) { | #[track_caller] | ||||||
|     world.despawn(entity); | 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.
 | /// An [`EntityCommand`] that adds the components in a [`Bundle`] to an entity.
 | ||||||
| #[track_caller] | #[track_caller] | ||||||
| fn insert<T: Bundle>(bundle: T) -> impl EntityCommand { | fn insert<T: Bundle>(bundle: T) -> impl EntityCommand { | ||||||
|     #[cfg(feature = "track_change_detection")] |  | ||||||
|     let caller = core::panic::Location::caller(); |     let caller = core::panic::Location::caller(); | ||||||
|     move |entity: Entity, world: &mut World| { |     move |entity: Entity, world: &mut World| { | ||||||
|         if let Some(mut entity) = world.get_entity_mut(entity) { |         if let Some(mut entity) = world.get_entity_mut(entity) { | ||||||
| @ -1317,7 +1322,7 @@ fn insert<T: Bundle>(bundle: T) -> impl EntityCommand { | |||||||
|                 caller, |                 caller, | ||||||
|             ); |             ); | ||||||
|         } else { |         } 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); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -55,7 +55,7 @@ use std::{ | |||||||
| 
 | 
 | ||||||
| #[cfg(feature = "track_change_detection")] | #[cfg(feature = "track_change_detection")] | ||||||
| use bevy_ptr::UnsafeCellDeref; | use bevy_ptr::UnsafeCellDeref; | ||||||
| #[cfg(feature = "track_change_detection")] | 
 | ||||||
| use core::panic::Location; | use core::panic::Location; | ||||||
| 
 | 
 | ||||||
| use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell}; | use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell}; | ||||||
| @ -1121,14 +1121,24 @@ impl World { | |||||||
|     /// assert!(world.get_entity(entity).is_none());
 |     /// assert!(world.get_entity(entity).is_none());
 | ||||||
|     /// assert!(world.get::<Position>(entity).is_none());
 |     /// assert!(world.get::<Position>(entity).is_none());
 | ||||||
|     /// ```
 |     /// ```
 | ||||||
|  |     #[track_caller] | ||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn despawn(&mut self, entity: Entity) -> bool { |     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(); |         self.flush(); | ||||||
|         if let Some(entity) = self.get_entity_mut(entity) { |         if let Some(entity) = self.get_entity_mut(entity) { | ||||||
|             entity.despawn(); |             entity.despawn(); | ||||||
|             true |             true | ||||||
|         } else { |         } 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 |             false | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 SpecificProtagonist
						SpecificProtagonist