Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/world/error.rs
6604 views
1
//! Contains error types returned by bevy's schedule.
2
3
use alloc::vec::Vec;
4
use bevy_utils::prelude::DebugName;
5
6
use 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.")]
17
pub 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:?}")]
26
pub 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}")]
36
pub 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)]
40
pub 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)]
51
pub 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)]
66
pub 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)]
79
mod 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
}
122
123