Thanks to visit codestin.com
Credit goes to docs.rs

bevy_ecs/world/
error.rs

1//! Contains error types returned by bevy's schedule.
2
3use alloc::vec::Vec;
4use bevy_utils::prelude::DebugName;
5
6use crate::{
7    component::ComponentId,
8    entity::{Entity, EntityDoesNotExistError},
9    schedule::InternedScheduleLabel,
10};
11
12/// The error type returned by [`World::try_run_schedule`] if the provided schedule does not exist.
13///
14/// [`World::try_run_schedule`]: crate::world::World::try_run_schedule
15#[derive(thiserror::Error, Debug)]
16#[error("The schedule with the label {0:?} was not found.")]
17pub struct TryRunScheduleError(pub InternedScheduleLabel);
18
19/// The error type returned by [`World::try_insert_batch`] and [`World::try_insert_batch_if_new`]
20/// if any of the provided entities do not exist.
21///
22/// [`World::try_insert_batch`]: crate::world::World::try_insert_batch
23/// [`World::try_insert_batch_if_new`]: crate::world::World::try_insert_batch_if_new
24#[derive(thiserror::Error, Debug, Clone)]
25#[error("Could not insert bundles of type {bundle_type} into the entities with the following IDs because they do not exist: {entities:?}")]
26pub struct TryInsertBatchError {
27    /// The bundles' type name.
28    pub bundle_type: DebugName,
29    /// The IDs of the provided entities that do not exist.
30    pub entities: Vec<Entity>,
31}
32
33/// An error that occurs when a specified [`Entity`] could not be despawned.
34#[derive(thiserror::Error, Debug, Clone, Copy)]
35#[error("Could not despawn entity: {0}")]
36pub struct EntityDespawnError(#[from] pub EntityMutableFetchError);
37
38/// An error that occurs when dynamically retrieving components from an entity.
39#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
40pub enum EntityComponentError {
41    /// The component with the given [`ComponentId`] does not exist on the entity.
42    #[error("The component with ID {0:?} does not exist on the entity.")]
43    MissingComponent(ComponentId),
44    /// The component with the given [`ComponentId`] was requested mutably more than once.
45    #[error("The component with ID {0:?} was requested mutably more than once.")]
46    AliasedMutability(ComponentId),
47}
48
49/// An error that occurs when fetching entities mutably from a world.
50#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
51pub enum EntityMutableFetchError {
52    /// The entity with the given ID does not exist.
53    #[error(
54        "{0}\n
55    If you were attempting to apply a command to this entity,
56    and want to handle this error gracefully, consider using `EntityCommands::queue_handled` or `queue_silenced`."
57    )]
58    EntityDoesNotExist(#[from] EntityDoesNotExistError),
59    /// The entity with the given ID was requested mutably more than once.
60    #[error("The entity with ID {0} was requested mutably more than once")]
61    AliasedMutability(Entity),
62}
63
64/// An error that occurs when getting a resource of a given type in a world.
65#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
66pub enum ResourceFetchError {
67    /// The resource has never been initialized or registered with the world.
68    #[error("The resource has never been initialized or registered with the world. Did you forget to add it using `app.insert_resource` / `app.init_resource`?")]
69    NotRegistered,
70    /// The resource with the given [`ComponentId`] does not currently exist in the world.
71    #[error("The resource with ID {0:?} does not currently exist in the world.")]
72    DoesNotExist(ComponentId),
73    /// Cannot get access to the resource with the given [`ComponentId`] in the world as it conflicts with an on going operation.
74    #[error("Cannot get access to the resource with ID {0:?} in the world as it conflicts with an on going operation.")]
75    NoResourceAccess(ComponentId),
76}
77
78#[cfg(test)]
79mod tests {
80    use crate::{
81        prelude::*,
82        system::{command::trigger, RunSystemOnce},
83    };
84
85    // Inspired by https://github.com/bevyengine/bevy/issues/19623
86    #[test]
87    fn fixing_panicking_entity_commands() {
88        #[derive(EntityEvent)]
89        struct Kill(Entity);
90
91        #[derive(EntityEvent)]
92        struct FollowupEvent(Entity);
93
94        fn despawn(kill: On<Kill>, mut commands: Commands) {
95            commands.entity(kill.event_target()).despawn();
96        }
97
98        fn followup(kill: On<Kill>, mut commands: Commands) {
99            // When using a simple .trigger() here, this panics because the entity has already been despawned.
100            // Instead, we need to use `.queue_handled` or `.queue_silenced` to avoid the panic.
101            commands.queue_silenced(trigger(FollowupEvent(kill.event_target())));
102        }
103
104        let mut world = World::new();
105        // This test would pass if the order of these statements were swapped,
106        // even with panicking entity commands
107        world.add_observer(followup);
108        world.add_observer(despawn);
109
110        // Create an entity to test these observers with
111        world.spawn_empty();
112
113        // Trigger a kill event on the entity
114        fn kill_everything(mut commands: Commands, query: Query<Entity>) {
115            for id in query.iter() {
116                commands.trigger(Kill(id));
117            }
118        }
119        world.run_system_once(kill_everything).unwrap();
120    }
121}