bevy_ecs/query/
error.rs

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