bevy_ecs/query/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use thiserror::Error;

use crate::{
    archetype::ArchetypeId,
    entity::{Entity, EntityDoesNotExistError},
};

/// An error that occurs when retrieving a specific [`Entity`]'s query result from [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState).
// TODO: return the type_name as part of this error
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum QueryEntityError {
    /// The given [`Entity`]'s components do not match the query.
    ///
    /// Either it does not have a requested component, or it has a component which the query filters out.
    QueryDoesNotMatch(Entity, ArchetypeId),
    /// The given [`Entity`] does not exist.
    EntityDoesNotExist(EntityDoesNotExistError),
    /// The [`Entity`] was requested mutably more than once.
    ///
    /// See [`Query::get_many_mut`](crate::system::Query::get_many_mut) for an example.
    AliasedMutability(Entity),
}

impl From<EntityDoesNotExistError> for QueryEntityError {
    fn from(error: EntityDoesNotExistError) -> Self {
        QueryEntityError::EntityDoesNotExist(error)
    }
}

impl core::error::Error for QueryEntityError {}

impl core::fmt::Display for QueryEntityError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match *self {
            Self::QueryDoesNotMatch(entity, _) => {
                write!(f, "The query does not match entity {entity}")
            }
            Self::EntityDoesNotExist(error) => {
                write!(f, "{error}")
            }
            Self::AliasedMutability(entity) => {
                write!(
                    f,
                    "The entity with ID {entity} was requested mutably more than once"
                )
            }
        }
    }
}

/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via
/// [`single`](crate::system::Query::single) or [`single_mut`](crate::system::Query::single_mut).
#[derive(Debug, Error)]
pub enum QuerySingleError {
    /// No entity fits the query.
    #[error("No entities fit the query {0}")]
    NoEntities(&'static str),
    /// Multiple entities fit the query.
    #[error("Multiple entities fit the query {0}")]
    MultipleEntities(&'static str),
}

#[cfg(test)]
mod test {
    use crate::{prelude::World, query::QueryEntityError};
    use bevy_ecs_macros::Component;

    #[test]
    fn query_does_not_match() {
        let mut world = World::new();

        #[derive(Component)]
        struct Present1;
        #[derive(Component)]
        struct Present2;
        #[derive(Component, Debug, PartialEq)]
        struct NotPresent;

        let entity = world.spawn((Present1, Present2));

        let (entity, archetype_id) = (entity.id(), entity.archetype().id());

        let result = world.query::<&NotPresent>().get(&world, entity);

        assert_eq!(
            result,
            Err(QueryEntityError::QueryDoesNotMatch(entity, archetype_id))
        );
    }
}