bevy_ecs/query/
error.rs

1use bevy_utils::prelude::DebugName;
2use thiserror::Error;
3
4use crate::{
5    archetype::ArchetypeId,
6    entity::{Entity, EntityDoesNotExistError},
7};
8
9/// An error that occurs when retrieving a specific [`Entity`]'s query result from [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState).
10// TODO: return the type_name as part of this error
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum QueryEntityError {
13    /// The given [`Entity`]'s components do not match the query.
14    ///
15    /// Either it does not have a requested component, or it has a component which the query filters out.
16    QueryDoesNotMatch(Entity, ArchetypeId),
17    /// The given [`Entity`] does not exist.
18    EntityDoesNotExist(EntityDoesNotExistError),
19    /// The [`Entity`] was requested mutably more than once.
20    ///
21    /// See [`Query::get_many_mut`](crate::system::Query::get_many_mut) for an example.
22    AliasedMutability(Entity),
23}
24
25impl From<EntityDoesNotExistError> for QueryEntityError {
26    fn from(error: EntityDoesNotExistError) -> Self {
27        QueryEntityError::EntityDoesNotExist(error)
28    }
29}
30
31impl core::error::Error for QueryEntityError {}
32
33impl core::fmt::Display for QueryEntityError {
34    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
35        match *self {
36            Self::QueryDoesNotMatch(entity, _) => {
37                write!(f, "The query does not match entity {entity}")
38            }
39            Self::EntityDoesNotExist(error) => {
40                write!(f, "{error}")
41            }
42            Self::AliasedMutability(entity) => {
43                write!(
44                    f,
45                    "The entity with ID {entity} was requested mutably more than once"
46                )
47            }
48        }
49    }
50}
51
52/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via
53/// [`single`](crate::system::Query::single) or [`single_mut`](crate::system::Query::single_mut).
54#[derive(Debug, Error)]
55pub enum QuerySingleError {
56    /// No entity fits the query.
57    #[error("No entities fit the query {0}")]
58    NoEntities(DebugName),
59    /// Multiple entities fit the query.
60    #[error("Multiple entities fit the query {0}")]
61    MultipleEntities(DebugName),
62}
63
64#[cfg(test)]
65mod test {
66    use crate::{prelude::World, query::QueryEntityError};
67    use bevy_ecs_macros::Component;
68
69    #[test]
70    fn query_does_not_match() {
71        let mut world = World::new();
72
73        #[derive(Component)]
74        struct Present1;
75        #[derive(Component)]
76        struct Present2;
77        #[derive(Component, Debug, PartialEq)]
78        struct NotPresent;
79
80        let entity = world.spawn((Present1, Present2));
81
82        let (entity, archetype_id) = (entity.id(), entity.archetype().id());
83
84        let result = world.query::<&NotPresent>().get(&world, entity);
85
86        assert_eq!(
87            result,
88            Err(QueryEntityError::QueryDoesNotMatch(entity, archetype_id))
89        );
90    }
91}