Derive Error for more error types (#10240)
# Objective Align all error-like types to implement `Error`. Fixes #10176 ## Solution - Derive `Error` on more types - Refactor instances of manual implementations that could be derived This adds thiserror as a dependency to bevy_transform, which might increase compilation time -- but I don't know of any situation where you might only use that but not any other crate that pulls in bevy_utils. The `contributors` example has a `LoadContributorsError` type, but as it's an example I have not updated it. Doing that would mean either having a `use bevy_internal::utils::thiserror::Error;` in an example file, or adding `thiserror` as a dev-dependency to the main `bevy` crate. --- ## Changelog - All `…Error` types now implement the `Error` trait
This commit is contained in:
parent
9d088dd144
commit
0c2c52a0cd
@ -8,7 +8,7 @@ use bevy_ecs::{
|
|||||||
ScheduleBuildSettings, ScheduleLabel,
|
ScheduleBuildSettings, ScheduleLabel,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bevy_utils::{intern::Interned, tracing::debug, HashMap, HashSet};
|
use bevy_utils::{intern::Interned, thiserror::Error, tracing::debug, HashMap, HashSet};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
panic::{catch_unwind, resume_unwind, AssertUnwindSafe},
|
panic::{catch_unwind, resume_unwind, AssertUnwindSafe},
|
||||||
@ -28,7 +28,9 @@ pub use bevy_utils::label::DynEq;
|
|||||||
/// A shorthand for `Interned<dyn AppLabel>`.
|
/// A shorthand for `Interned<dyn AppLabel>`.
|
||||||
pub type InternedAppLabel = Interned<dyn AppLabel>;
|
pub type InternedAppLabel = Interned<dyn AppLabel>;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
pub(crate) enum AppError {
|
pub(crate) enum AppError {
|
||||||
|
#[error("duplicate plugin {plugin_name:?}")]
|
||||||
DuplicatePlugin { plugin_name: String },
|
DuplicatePlugin { plugin_name: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,41 +1,28 @@
|
|||||||
use std::fmt;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::entity::Entity;
|
use crate::entity::Entity;
|
||||||
|
|
||||||
/// An error that occurs when retrieving a specific [`Entity`]'s query result from [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState).
|
/// 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
|
// TODO: return the type_name as part of this error
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Error)]
|
||||||
pub enum QueryEntityError {
|
pub enum QueryEntityError {
|
||||||
/// The given [`Entity`]'s components do not match the query.
|
/// 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.
|
/// Either it does not have a requested component, or it has a component which the query filters out.
|
||||||
|
#[error("The components of entity {0:?} do not match the query")]
|
||||||
QueryDoesNotMatch(Entity),
|
QueryDoesNotMatch(Entity),
|
||||||
/// The given [`Entity`] does not exist.
|
/// The given [`Entity`] does not exist.
|
||||||
|
#[error("The entity {0:?} does not exist")]
|
||||||
NoSuchEntity(Entity),
|
NoSuchEntity(Entity),
|
||||||
/// The [`Entity`] was requested mutably more than once.
|
/// The [`Entity`] was requested mutably more than once.
|
||||||
///
|
///
|
||||||
/// See [`QueryState::get_many_mut`](crate::query::QueryState::get_many_mut) for an example.
|
/// See [`QueryState::get_many_mut`](crate::query::QueryState::get_many_mut) for an example.
|
||||||
|
#[error("The entity {0:?} was requested mutably more than once")]
|
||||||
AliasedMutability(Entity),
|
AliasedMutability(Entity),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for QueryEntityError {}
|
|
||||||
|
|
||||||
impl fmt::Display for QueryEntityError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
QueryEntityError::QueryDoesNotMatch(_) => {
|
|
||||||
write!(f, "The given entity's components do not match the query.")
|
|
||||||
}
|
|
||||||
QueryEntityError::NoSuchEntity(_) => write!(f, "The requested entity does not exist."),
|
|
||||||
QueryEntityError::AliasedMutability(_) => {
|
|
||||||
write!(f, "The entity was requested mutably more than once.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`](crate::system::Query).
|
/// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`](crate::system::Query).
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq, Error)]
|
||||||
pub enum QueryComponentError {
|
pub enum QueryComponentError {
|
||||||
/// The [`Query`](crate::system::Query) does not have read access to the requested component.
|
/// The [`Query`](crate::system::Query) does not have read access to the requested component.
|
||||||
///
|
///
|
||||||
@ -66,6 +53,7 @@ pub enum QueryComponentError {
|
|||||||
/// }
|
/// }
|
||||||
/// # bevy_ecs::system::assert_is_system(get_missing_read_access_error);
|
/// # bevy_ecs::system::assert_is_system(get_missing_read_access_error);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[error("This query does not have read access to the requested component")]
|
||||||
MissingReadAccess,
|
MissingReadAccess,
|
||||||
/// The [`Query`](crate::system::Query) does not have write access to the requested component.
|
/// The [`Query`](crate::system::Query) does not have write access to the requested component.
|
||||||
///
|
///
|
||||||
@ -93,59 +81,24 @@ pub enum QueryComponentError {
|
|||||||
/// }
|
/// }
|
||||||
/// # bevy_ecs::system::assert_is_system(get_missing_write_access_error);
|
/// # bevy_ecs::system::assert_is_system(get_missing_write_access_error);
|
||||||
/// ```
|
/// ```
|
||||||
|
#[error("This query does not have write access to the requested component")]
|
||||||
MissingWriteAccess,
|
MissingWriteAccess,
|
||||||
/// The given [`Entity`] does not have the requested component.
|
/// The given [`Entity`] does not have the requested component.
|
||||||
|
#[error("The given entity does not have the requested component")]
|
||||||
MissingComponent,
|
MissingComponent,
|
||||||
/// The requested [`Entity`] does not exist.
|
/// The requested [`Entity`] does not exist.
|
||||||
|
#[error("The requested entity does not exist")]
|
||||||
NoSuchEntity,
|
NoSuchEntity,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for QueryComponentError {}
|
|
||||||
|
|
||||||
impl std::fmt::Display for QueryComponentError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
QueryComponentError::MissingReadAccess => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"This query does not have read access to the requested component."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
QueryComponentError::MissingWriteAccess => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"This query does not have write access to the requested component."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
QueryComponentError::MissingComponent => {
|
|
||||||
write!(f, "The given entity does not have the requested component.")
|
|
||||||
}
|
|
||||||
QueryComponentError::NoSuchEntity => {
|
|
||||||
write!(f, "The requested entity does not exist.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via
|
/// An error that occurs when evaluating a [`Query`](crate::system::Query) or [`QueryState`](crate::query::QueryState) as a single expected result via
|
||||||
/// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut).
|
/// [`get_single`](crate::system::Query::get_single) or [`get_single_mut`](crate::system::Query::get_single_mut).
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum QuerySingleError {
|
pub enum QuerySingleError {
|
||||||
/// No entity fits the query.
|
/// No entity fits the query.
|
||||||
|
#[error("No entities fit the query {0}")]
|
||||||
NoEntities(&'static str),
|
NoEntities(&'static str),
|
||||||
/// Multiple entities fit the query.
|
/// Multiple entities fit the query.
|
||||||
|
#[error("Multiple entities fit the query {0}")]
|
||||||
MultipleEntities(&'static str),
|
MultipleEntities(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for QuerySingleError {}
|
|
||||||
|
|
||||||
impl std::fmt::Display for QuerySingleError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
QuerySingleError::NoEntities(query) => write!(f, "No entities fit the query {query}"),
|
|
||||||
QuerySingleError::MultipleEntities(query) => {
|
|
||||||
write!(f, "Multiple entities fit the query {query}!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use crate::system::{BoxedSystem, Command, IntoSystem};
|
|||||||
use crate::world::World;
|
use crate::world::World;
|
||||||
use crate::{self as bevy_ecs};
|
use crate::{self as bevy_ecs};
|
||||||
use bevy_ecs_macros::Component;
|
use bevy_ecs_macros::Component;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
/// A small wrapper for [`BoxedSystem`] that also keeps track whether or not the system has been initialized.
|
/// A small wrapper for [`BoxedSystem`] that also keeps track whether or not the system has been initialized.
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
@ -197,15 +198,18 @@ impl Command for RunSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An operation with stored systems failed.
|
/// An operation with stored systems failed.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum RegisteredSystemError {
|
pub enum RegisteredSystemError {
|
||||||
/// A system was run by id, but no system with that id was found.
|
/// A system was run by id, but no system with that id was found.
|
||||||
///
|
///
|
||||||
/// Did you forget to register it?
|
/// Did you forget to register it?
|
||||||
|
#[error("System {0:?} was not registered")]
|
||||||
SystemIdNotRegistered(SystemId),
|
SystemIdNotRegistered(SystemId),
|
||||||
/// A system tried to run itself recursively.
|
/// A system tried to run itself recursively.
|
||||||
|
#[error("System {0:?} tried to run itself recursively")]
|
||||||
Recursive(SystemId),
|
Recursive(SystemId),
|
||||||
/// A system tried to remove itself.
|
/// A system tried to remove itself.
|
||||||
|
#[error("System {0:?} tried to remove itself")]
|
||||||
SelfRemove(SystemId),
|
SelfRemove(SystemId),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,10 +6,12 @@ use bevy_ecs::{
|
|||||||
schedule::SystemConfigs,
|
schedule::SystemConfigs,
|
||||||
system::{StaticSystemParam, SystemParam, SystemParamItem},
|
system::{StaticSystemParam, SystemParam, SystemParamItem},
|
||||||
};
|
};
|
||||||
use bevy_utils::{HashMap, HashSet};
|
use bevy_utils::{thiserror::Error, HashMap, HashSet};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
pub enum PrepareAssetError<E: Send + Sync + 'static> {
|
pub enum PrepareAssetError<E: Send + Sync + 'static> {
|
||||||
|
#[error("Failed to prepare asset")]
|
||||||
RetryNextUpdate(E),
|
RetryNextUpdate(E),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::{
|
|||||||
texture::FallbackImage,
|
texture::FallbackImage,
|
||||||
};
|
};
|
||||||
pub use bevy_render_macros::AsBindGroup;
|
pub use bevy_render_macros::AsBindGroup;
|
||||||
|
use bevy_utils::thiserror::Error;
|
||||||
use encase::ShaderType;
|
use encase::ShaderType;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use wgpu::{BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource};
|
use wgpu::{BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource};
|
||||||
@ -325,8 +326,10 @@ pub trait AsBindGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error that occurs during [`AsBindGroup::as_bind_group`] calls.
|
/// An error that occurs during [`AsBindGroup::as_bind_group`] calls.
|
||||||
|
#[derive(Debug, Error)]
|
||||||
pub enum AsBindGroupError {
|
pub enum AsBindGroupError {
|
||||||
/// The bind group could not be generated. Try again next frame.
|
/// The bind group could not be generated. Try again next frame.
|
||||||
|
#[error("The bind group could not be generated")]
|
||||||
RetryNextUpdate,
|
RetryNextUpdate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.12.0-dev" }
|
|||||||
bevy_math = { path = "../bevy_math", version = "0.12.0-dev" }
|
bevy_math = { path = "../bevy_math", version = "0.12.0-dev" }
|
||||||
bevy_reflect = { path = "../bevy_reflect", version = "0.12.0-dev", features = ["bevy"] }
|
bevy_reflect = { path = "../bevy_reflect", version = "0.12.0-dev", features = ["bevy"] }
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bevy_tasks = { path = "../bevy_tasks", version = "0.12.0-dev" }
|
bevy_tasks = { path = "../bevy_tasks", version = "0.12.0-dev" }
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use bevy_ecs::{
|
|||||||
system::{Query, SystemParam},
|
system::{Query, SystemParam},
|
||||||
};
|
};
|
||||||
use bevy_hierarchy::{HierarchyQueryExt, Parent};
|
use bevy_hierarchy::{HierarchyQueryExt, Parent};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::components::{GlobalTransform, Transform};
|
use crate::components::{GlobalTransform, Transform};
|
||||||
|
|
||||||
@ -63,14 +64,17 @@ fn map_error(err: QueryEntityError, ancestor: bool) -> ComputeGlobalTransformErr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Error returned by [`TransformHelper::compute_global_transform`].
|
/// Error returned by [`TransformHelper::compute_global_transform`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ComputeGlobalTransformError {
|
pub enum ComputeGlobalTransformError {
|
||||||
/// The entity or one of its ancestors is missing the [`Transform`] component.
|
/// The entity or one of its ancestors is missing the [`Transform`] component.
|
||||||
|
#[error("The entity {0:?} or one of its ancestors is missing the `Transform` component")]
|
||||||
MissingTransform(Entity),
|
MissingTransform(Entity),
|
||||||
/// The entity does not exist.
|
/// The entity does not exist.
|
||||||
|
#[error("The entity {0:?} does not exist")]
|
||||||
NoSuchEntity(Entity),
|
NoSuchEntity(Entity),
|
||||||
/// An ancestor is missing.
|
/// An ancestor is missing.
|
||||||
/// This probably means that your hierarchy has been improperly maintained.
|
/// This probably means that your hierarchy has been improperly maintained.
|
||||||
|
#[error("The ancestor {0:?} is missing")]
|
||||||
MalformedHierarchy(Entity),
|
MalformedHierarchy(Entity),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use bevy_utils::{default, HashMap};
|
|||||||
use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged};
|
use bevy_window::{PrimaryWindow, Window, WindowResolution, WindowScaleFactorChanged};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use taffy::Taffy;
|
use taffy::Taffy;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub struct LayoutContext {
|
pub struct LayoutContext {
|
||||||
pub scale_factor: f64,
|
pub scale_factor: f64,
|
||||||
@ -228,10 +229,12 @@ with UI components as a child of an entity without UI components, results may be
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum LayoutError {
|
pub enum LayoutError {
|
||||||
|
#[error("Invalid hierarchy")]
|
||||||
InvalidHierarchy,
|
InvalidHierarchy,
|
||||||
TaffyError(taffy::error::TaffyError),
|
#[error("Taffy error: {0}")]
|
||||||
|
TaffyError(#[from] taffy::error::TaffyError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes.
|
/// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes.
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
//! This example displays each contributor to the bevy source code as a bouncing bevy-ball.
|
//! This example displays each contributor to the bevy source code as a bouncing bevy-ball.
|
||||||
|
|
||||||
use bevy::{prelude::*, utils::HashSet};
|
use bevy::{
|
||||||
|
prelude::*,
|
||||||
|
utils::{thiserror, HashSet},
|
||||||
|
};
|
||||||
use rand::{prelude::SliceRandom, Rng};
|
use rand::{prelude::SliceRandom, Rng};
|
||||||
use std::{
|
use std::{
|
||||||
env::VarError,
|
env::VarError,
|
||||||
@ -309,9 +312,13 @@ fn move_system(time: Res<Time>, mut query: Query<(&Velocity, &mut Transform)>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
enum LoadContributorsError {
|
enum LoadContributorsError {
|
||||||
IO(io::Error),
|
#[error("An IO error occurred while reading the git log.")]
|
||||||
Var(VarError),
|
Io(#[from] io::Error),
|
||||||
|
#[error("The CARGO_MANIFEST_DIR environment variable was not set.")]
|
||||||
|
Var(#[from] VarError),
|
||||||
|
#[error("The git process did not return a stdout handle.")]
|
||||||
Stdout,
|
Stdout,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,14 +328,13 @@ enum LoadContributorsError {
|
|||||||
/// This function only works if `git` is installed and
|
/// This function only works if `git` is installed and
|
||||||
/// the program is run through `cargo`.
|
/// the program is run through `cargo`.
|
||||||
fn contributors() -> Result<Contributors, LoadContributorsError> {
|
fn contributors() -> Result<Contributors, LoadContributorsError> {
|
||||||
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").map_err(LoadContributorsError::Var)?;
|
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
|
||||||
|
|
||||||
let mut cmd = std::process::Command::new("git")
|
let mut cmd = std::process::Command::new("git")
|
||||||
.args(["--no-pager", "log", "--pretty=format:%an"])
|
.args(["--no-pager", "log", "--pretty=format:%an"])
|
||||||
.current_dir(manifest_dir)
|
.current_dir(manifest_dir)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()?;
|
||||||
.map_err(LoadContributorsError::IO)?;
|
|
||||||
|
|
||||||
let stdout = cmd.stdout.take().ok_or(LoadContributorsError::Stdout)?;
|
let stdout = cmd.stdout.take().ok_or(LoadContributorsError::Stdout)?;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user