Pass panics to the fallback error handler#24240
Open
SpecificProtagonist wants to merge 13 commits into
Open
Conversation
| Err(payload) if PANIC_ORIGINATES_FROM_ERROR_HANDLER.replace(false) => { | ||
| (None, Err(payload)) | ||
| } | ||
| // We can ignore the panic payload here, as it will have already been printed. |
Contributor
Author
There was a problem hiding this comment.
By default, the panic handler will have already printed the panic payload, but we could add it to the error message given to the error handler too.
| Err(_) => { | ||
| let err = BevyError::new_with_backtrace( | ||
| Severity::Panic, | ||
| "System panicked", |
Contributor
Author
There was a problem hiding this comment.
I'm using only an error message here, but if desired I could create a structured error that can be BevyError::downcast_refed.
Comment on lines
+134
to
+137
| /// When deliberately throwing a panic in your [`ErrorHandler`], | ||
| /// set this to true to indicate to the executor that the panic | ||
| /// should not be turned back into a [`BevyError`]. | ||
| pub static PANIC_ORIGINATES_FROM_ERROR_HANDLER: core::cell::Cell<bool> = const {core::cell::Cell::new(false)}; |
Contributor
Author
There was a problem hiding this comment.
This is not particularly elegant, but works and is easier to use than if for all error handlers we were to force a wrapper that set this to true, calls the error handler and then sets it to false again.
chescock
reviewed
May 11, 2026
Contributor
chescock
left a comment
There was a problem hiding this comment.
Yeah, being able to recover from panics seems like a really important part of making Bevy robust!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Currently, a panic (whether from engine or user code, as there is little distinction) takes down the entire app with it. Instead the user should be able to decide how the error is handled. This is currently not possible except by writing your own executor and setting it for all relevant schedules.
See for comparison Godot's policy on exceptions:
Unity will also log an error and then continue if user code throws an exception. I believe Unreal does too for exceptions coming from Blueprints. Similarly, many web servers will respond with an error to a request that threw an exception, but will not crash the server itself.
This PR does not enable this behavior by default, but makes it user-configurable.
Also fixes #19109
Also (I think) fixes #7434
Solution
Instead of rethrowing panics, hand them to the
FallbackErrorHandler.If the panic was thrown by an error handler in the first place, we don't need to pass it back to a handler again. I've added a way for the error handler to signal that it's the source of the panic.
The constructed error is created without a backtrace, as the default panic handler already prints it when instructed to via
RUST_LIB_BACKTRACE/RUST_BACKTRACE.Panics will not be turned into errors on
no_stdprojects.Testing
See added
panic_to_errortest