Skip to content

Simplified system error handling #18297

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

Conversation

alice-i-cecile
Copy link
Member

Objective

While working towards #17272, I found a few things to clean up for system error handling. Since I intend to mostly use the system error handling approach for both systems and commands, I wanted to clean it up and reduce complexity before porting commands over to it to.

This is a good, simple stopping point for review, so here's the second PR in the series :)

Solution

  • rename the fallible_systems example to the less mysterious and more general error_handling
  • rename DefaultSystemErrorHandler to the more general and more informative FallbackErrorHandler
  • remove the helper methods on App and SubApp for configuring this: all they do is set a value of a resource
  • remove the per-schedule error handlers: this is a fair bit of added complexity and inconsistency that can result in accidentally missing logs or shipping panics and no clear motivating user story exists

Testing

  • error_handling example works as intended

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Code-Quality A section of code that is hard to understand or change C-Usability A targeted quality-of-life change that makes Bevy easier to use X-Contentious There are nontrivial implications that should be thought through D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 13, 2025
Copy link
Contributor

You added a new example but didn't add metadata for it. Please update the root Cargo.toml file.

@@ -449,7 +440,7 @@ impl Schedule {
self.initialize(world)
.unwrap_or_else(|e| panic!("Error when initializing schedule {:?}: {e}", self.label));

let error_handler = self.error_handler.expect("schedule initialized");
let error_handler = world.get_resource_or_init::<FallbackErrorHandler>().0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FallbackErrorHandler is mentioned as the thing that bevy will use if nothing else is provided- I assume this PR is an initial step and then this code will be updated later to grab the appropriate configured error handler for use at runtime?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular line of code is in its final form. There's other localized mechanisms of error handling, like system piping, which is what the docs on FallbackErrorHandling refer to. When those are used, this error handler is never called at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, I see because when systems are piped only the outermost system, if it returns a Result::Err will trigger this. Thanks for the context!

@krunchington
Copy link
Contributor

many deleted lines make grug brain dev happy. The resource initialization pattern without providing the redundant helper methods makes a ton of sense.

@@ -10,12 +10,19 @@ pub struct SystemErrorContext {
pub last_run: Tick,
}

/// The default systems error handler stored as a resource in the [`World`](crate::world::World).
pub struct DefaultSystemErrorHandler(pub fn(BevyError, SystemErrorContext));
/// The error handler of last resort used for [`bevy_ecs::error::Result`]s returned by systems, commands and observers,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not currently used by commands (largely for performance reasons).

///
/// See [`bevy_ecs::error`] for more information on error handling,
/// and [`bevy_ecs::error::handler`] for an assortment of built-in error handlers.
pub struct FallbackErrorHandler(pub fn(BevyError, SystemErrorContext));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the appeal of removing System, but as a user if I was going to change this, I would ask myself "how do I set the default bevy error handler". I also think it "fits". People tend to consider defaults "overridable".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, this would no longer be "overridable" in the sense of inserting a resource that takes precedence- is that correct? If so then avoiding the term "default" may fit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I guess you can override it but you'd be overriding it by instantiating a new instance of this struct. So a custom error handler doing world.insert_resource(DefaultErrorHandler(... would feel weird.

Maybe a name like ScheduleErrorHandler or RuntimeErrorHandler for the struct makes more sense?

Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@krunchington
Copy link
Contributor

The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.

@alice-i-cecile I was going to pr another change to run this, but it looks like the table formatting may have changed in an update to the generation script- if this looks intentional I can send a PR for it?
image

@alice-i-cecile
Copy link
Member Author

Closing out; going to try moving to the command-based design instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Code-Quality A section of code that is hard to understand or change C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants