-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Command
error handling
#2241
Command
error handling
#2241
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! Can you add an example for this? It feels like it belongs beside the testing example, but you'll need to change the folder name.
I would prefer to use a |
this is a fair concern, however is it possible to create a system without allocations? Also, I feel this adds a lot of unnecessary baggage to what is supposed to be a simple error handler. |
I was thinking that it might be valuable to have a global error handling for certain classes of error, but on reflection I feel that's an antipattern. I think that the better approach is going to be to provide nice functionality for enforcing error handling in whatever form as part of a Bevy-specific linter (#1602). |
Not sure, it would probably be hard to capture all the types needed for a
Why not? I'm not sure of the impact of Boxing a system.
It's more baggage in the implementation, but I feel it's less for the user. but then as there's world access, you end up using the same api in your error handler as in an exclusive system, right? |
IME reading / writing normal systems is much easier than exclusive systems, in large part due to the implicit documentation of the function parameters. This also makes any future migration to running these things in automatic parallel much less painful, since they're already scoped. |
Yea that's fair :)
It's just extra memory allocations that I'm trying to avoid if possible. |
Personally I'd rather not make it so just adding an error handler requires an heap allocation, as this will discourage adding them. Another point is that while exclusive systems can run regular systems, and there are plans to make direct world access more ergonomic with a more system-like API, the reverse isn't true. I'd recommend having a barebones error handling mechanism directly based on &mut World, especially for this first PR. |
Having seen the results of your experiment, I think @TheRawMeatball is probably right above, as much as it pains me to encourage more "operate directly on the entire world" logic. This needs to be ergonomic, and the heap allocation is a little 😬. |
4ba1911
to
760a9e1
Compare
Command
error handling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks nice! This should be very useful.
In addition to my comments, I'd like to see:
- User-facing example code.
- Unhappy-path tests for each fallible command to verify that they do in fact error when we expect them to.
ecfe507
to
bbb4e5d
Compare
3f13a88
to
aa166a9
Compare
This is a very serious improvement, and will make using commands much safer. I would expect us to persist with this style of API in some form even as we reduce our reliance on Commands per se moving forward. |
Just gave this a look. I think this is generally the right direction (until we overhaul Commands). I think the multiple on_err / on_err_do functions are a bit confusing. And the types + inference are a bit unwieldy. I just pushed some (proposed) changes that simplify the implementation, remove the need for on_err_do, and improve ergonomics in some cases. With these changes, only a single I think we should do a quick benchmark to see what this error handling costs us in practice compared to the previous impl. Probably something along the lines of:
|
We can use the commands bench-marking from #2334 once that gets merged. |
1857ccd
to
64546c4
Compare
I ran some perf-tests for this and had the following results: group DESPAWN-ERROR-MAIN DESPAWN-ERROR-NEW
----- ------------------ -----------------
despawn_error/0_entities 1.00 10.0±0.46ns ? ?/sec 1.03 10.2±0.26ns ? ?/sec
despawn_error/1000_entities 1.00 54.6±2.26µs ? ?/sec 1.07 58.7±2.70µs ? ?/sec
despawn_error/1500_entities 1.00 77.1±1.92µs ? ?/sec 1.12 86.5±2.70µs ? ?/sec
despawn_error/2000_entities 1.00 103.4±3.29µs ? ?/sec 1.10 114.2±4.72µs ? ?/sec
despawn_error/500_entities 1.00 29.6±0.74µs ? ?/sec 1.07 31.7±1.63µs ? ?/sec The error-handling version (unsurprisingly) took a little performance hit since now we store an error-handler, and there is extra logic for when you actually add an error handler. |
pinging here. |
Yes please! I'd be happy to review this again once it's ready. There may be light changes to how commands work with upcoming scheduler work, but I don't think anything that's likely to conflict. |
@NathanSWard I'm looking to revive this; would you prefer I create new PR, make PRs to this or be granted write permissions to your fork? |
To anyone who is interested, I picked up this PR and created a new one per the guidelines, you can find it here: |
Closing as adopted :) |
Fixes: #2004
Some new traits were introducted:
FallibleCommand
CommandErrorHandling
If a command is fallible, then new return type is a
Config
type.The
Config
type allows a user to optionally provide an error handler viaon_err_do
.However, I added some builtin handlers (via
CommandErrorHandler
) likeignore()
panic()
andlog()
for some typical use cases of what someone might want to do with an error.note: the default behavior is
log()
. None of the commands willpanic!
but will instead log the error viaerror!
.EXAMPLES: