Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document query errors #8692

Merged
merged 8 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions crates/bevy_ecs/src/query/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,12 +1162,19 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
}
}

/// 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.
alice-i-cecile marked this conversation as resolved.
Show resolved Hide resolved
AliasedMutability(Entity),
}

Expand All @@ -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(_) => {
Expand Down Expand Up @@ -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),
}

Expand Down
63 changes: 60 additions & 3 deletions crates/bevy_ecs/src/system/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand Down Expand Up @@ -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
///
Expand Down Expand Up @@ -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<SpecificEntity>) {
/// assert_eq!(
/// query.get_component::<RequestedComponent>(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<SpecificEntity>) {
/// assert_eq!(
/// query.get_component::<RequestedComponent>(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,
}

Expand Down