From ca81d3e4359f158bcf2e20e77d82d7ab52daafc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9l=C3=A8ne=20Amanita?= <134181069+Selene-Amanita@users.noreply.github.com> Date: Tue, 30 May 2023 15:41:14 +0100 Subject: [PATCH] Document query errors (#8692) # Objective Add documentation to `Query` and `QueryState` errors in bevy_ecs (`QuerySingleError`, `QueryEntityError`, `QueryComponentError`) ## Solution - Change display message for `QueryEntityError::QueryDoesNotMatch`: this error can also happen when the entity has a component which is filtered out (with `Without`) - Fix wrong reference in the documentation of `Query::get_component` and `Query::get_component_mut` from `QueryEntityError` to `QueryComponentError` - Complete the documentation of the three error enum variants. - Add examples for `QueryComponentError::MissingReadAccess` and `QueryComponentError::MissingWriteAccess` - Add reference to `QueryState` in `QueryEntityError`'s documentation. --- ## Migration Guide Expect `QueryEntityError::QueryDoesNotMatch`'s display message to change? Not sure that counts. --------- Co-authored-by: harudagondi --- crates/bevy_ecs/src/query/state.rs | 17 ++++++-- crates/bevy_ecs/src/system/query.rs | 63 +++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 49b4d7202420e..b5ccf8263e233 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -1162,12 +1162,19 @@ impl QueryState { } } -/// An error that occurs when retrieving a specific [`Entity`]'s query result. +/// An error that occurs when retrieving a specific [`Entity`]'s query result from [`Query`](crate::system::Query) or [`QueryState`]. // TODO: return the type_name as part of this error #[derive(Debug, PartialEq, Eq, Clone, Copy)] 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), + /// The given [`Entity`] does not exist. NoSuchEntity(Entity), + /// The [`Entity`] was requested mutably more than once. + /// + /// See [`QueryState::get_many_mut`] for an example. AliasedMutability(Entity), } @@ -1177,7 +1184,7 @@ impl fmt::Display for QueryEntityError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { QueryEntityError::QueryDoesNotMatch(_) => { - write!(f, "The given entity does not have the requested component.") + write!(f, "The given entity's components do not match the query.") } QueryEntityError::NoSuchEntity(_) => write!(f, "The requested entity does not exist."), QueryEntityError::AliasedMutability(_) => { @@ -1296,11 +1303,13 @@ mod tests { } } -/// An error that occurs when evaluating a [`QueryState`] as a single expected resulted via -/// [`QueryState::single`] or [`QueryState::single_mut`]. +/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`] as a single expected result via +/// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut). #[derive(Debug)] pub enum QuerySingleError { + /// No entity fits the query. NoEntities(&'static str), + /// Multiple entities fit the query. MultipleEntities(&'static str), } diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 4316389adecc1..1e18705dcede0 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -1054,7 +1054,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> { /// Returns a mutable reference to the component `T` of the given entity. /// - /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. + /// In case of a nonexisting entity or mismatched component, a [`QueryComponentError`] is returned instead. /// /// # Example /// @@ -1090,7 +1090,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> { /// Returns a mutable reference to the component `T` of the given entity. /// - /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. + /// In case of a nonexisting entity or mismatched component, a [`QueryComponentError`] is returned instead. /// /// # Safety /// @@ -1357,12 +1357,69 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> IntoIterator for &'w mut Quer } } -/// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`] +/// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`]. #[derive(Debug, PartialEq, Eq)] pub enum QueryComponentError { + /// The [`Query`] does not have read access to the requested component. + /// + /// This error occurs when the requested component is not included in the original query. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::{prelude::*, system::QueryComponentError}; + /// # + /// # #[derive(Component)] + /// # struct OtherComponent; + /// # + /// # #[derive(Component, PartialEq, Debug)] + /// # struct RequestedComponent; + /// # + /// # #[derive(Resource)] + /// # struct SpecificEntity { + /// # entity: Entity, + /// # } + /// # + /// fn get_missing_read_access_error(query: Query<&OtherComponent>, res: Res) { + /// assert_eq!( + /// query.get_component::(res.entity), + /// Err(QueryComponentError::MissingReadAccess), + /// ); + /// println!("query doesn't have read access to RequestedComponent because it does not appear in Query<&OtherComponent>"); + /// } + /// # bevy_ecs::system::assert_is_system(get_missing_read_access_error); + /// ``` MissingReadAccess, + /// The [`Query`] does not have write access to the requested component. + /// + /// This error occurs when the requested component is not included in the original query, or the mutability of the requested component is mismatched with the original query. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::{prelude::*, system::QueryComponentError}; + /// # + /// # #[derive(Component, PartialEq, Debug)] + /// # struct RequestedComponent; + /// # + /// # #[derive(Resource)] + /// # struct SpecificEntity { + /// # entity: Entity, + /// # } + /// # + /// fn get_missing_write_access_error(mut query: Query<&RequestedComponent>, res: Res) { + /// assert_eq!( + /// query.get_component::(res.entity), + /// Err(QueryComponentError::MissingWriteAccess), + /// ); + /// println!("query doesn't have write access to RequestedComponent because it doesn't have &mut in Query<&RequestedComponent>"); + /// } + /// # bevy_ecs::system::assert_is_system(get_missing_write_access_error); + /// ``` MissingWriteAccess, + /// The given [`Entity`] does not have the requested component. MissingComponent, + /// The requested [`Entity`] does not exist. NoSuchEntity, }