Better warnings about invalid parameters#15500
Better warnings about invalid parameters#15500alice-i-cecile merged 14 commits intobevyengine:mainfrom
Conversation
cd2fe8d to
0bd22bb
Compare
|
I've noticed some problems with this approach, I'll be reworking it |
d217110 to
8e2c754
Compare
…15526) # Objective Fixes #15394 ## Solution Observers now validate params. System registry has a new error variant for when system running fails due to invalid parameters. Run once now returns a `Result<Out, RunOnceError>` instead of `Out`. This is more inline with system registry, which also returns a result. I'll address warning messages in #15500. ## Testing Added one test for each case. --- ## Migration Guide - `RunSystemOnce::run_system_once` and `RunSystemOnce::run_system_once_with` now return a `Result<Out>` instead of just `Out` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Zachary Harrold <zac@harrold.com.au>
c12cb04 to
5f1cdb5
Compare
|
Trying to construct a worst-case benchmark, where the systems do no work and there are no parameters to validate or extract: let mut world = World::new();
let mut schedule = Schedule::default();
for _ in 0..1000 {
schedule.add_systems(|| ());
}
for _ in 0..1000000 {
schedule.run(&mut world);
}So there's about a standard deviation difference. But if these numbers were precise, the feature flag would allow removing 0.178ns per system. I don't think that's worth it. |
|
Thank you for your work, I'll remove the flag when im home :) |
chescock
left a comment
There was a problem hiding this comment.
So the warning is now emitted from the param itself, which lets you include the param type in the message. And the warning state is stored on the system, which saves space and is easier to configure. As a consequence, if a system has multiple failing parameters, it only warns on the first one, right? That all seems reasonable, although the final result is a little surprising.
The policy update of a (function) system happens after param validation fails. While we can remove the short circuit, this won't patch a hole where missing parameters can change over time and we'll still only get warning about the first one (time-wise). I guess we could store the warning per system param?? |
bushrat011899
left a comment
There was a problem hiding this comment.
Looks good to me, love the idea of giving more meaningful feedback to the user without spamming them needlessly. I have a note about a possible future PR, but definitely doesn't need to be in this PR.
| /// No warning should ever be emitted. | ||
| Never, | ||
| /// The warning will be emitted once and status will update to [`Self::Never`]. | ||
| Once, |
There was a problem hiding this comment.
Future PR: Seems reasonable to add an Always policy as well:
/// State machine for emitting warnings when [system params are invalid](System::validate_param).
#[derive(Clone, Copy)]
pub enum ParamWarnPolicy {
/// No warning should ever be emitted.
Never,
/// The warning will be emitted once and status will update to [`Self::Never`].
Once,
/// The warning will be emitted each time the system is run.
Always,
}There was a problem hiding this comment.
I had it but removed it as per previous feedback.
I think Always will be a bit too annoying, but we could certainly use more complex policies:
- system just stopped running (prev frame valid, this frame invalid)
- invalid params changed
If we get some higher level logging with editor, we can do stuff like:
- system X stopped running at frame N because of invalid param P and is still not running till frame M
Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
# Objective System param validation warnings should be configurable and default to "warn once" (per system). Fixes: bevyengine#15391 ## Solution `SystemMeta` is given a new `ParamWarnPolicy` field. The policy decides whether warnings will be emitted by each system param when it fails validation. The policy is updated by the system after param validation fails. Example warning: ``` 2024-09-30T18:10:04.740749Z WARN bevy_ecs::system::function_system: System fallible_params::do_nothing_fail_validation will not run because it requested inaccessible system parameter Single<(), (With<Player>, With<Enemy>)> ``` Currently, only the first invalid parameter is displayed. Warnings can be disabled on function systems using `.param_never_warn()`. (there is also `.with_param_warn_policy(policy)`) ## Testing Ran `fallible_params` example. --------- Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
…evyengine#15526) # Objective Fixes bevyengine#15394 ## Solution Observers now validate params. System registry has a new error variant for when system running fails due to invalid parameters. Run once now returns a `Result<Out, RunOnceError>` instead of `Out`. This is more inline with system registry, which also returns a result. I'll address warning messages in bevyengine#15500. ## Testing Added one test for each case. --- ## Migration Guide - `RunSystemOnce::run_system_once` and `RunSystemOnce::run_system_once_with` now return a `Result<Out>` instead of just `Out` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Zachary Harrold <zac@harrold.com.au>
# Objective System param validation warnings should be configurable and default to "warn once" (per system). Fixes: bevyengine#15391 ## Solution `SystemMeta` is given a new `ParamWarnPolicy` field. The policy decides whether warnings will be emitted by each system param when it fails validation. The policy is updated by the system after param validation fails. Example warning: ``` 2024-09-30T18:10:04.740749Z WARN bevy_ecs::system::function_system: System fallible_params::do_nothing_fail_validation will not run because it requested inaccessible system parameter Single<(), (With<Player>, With<Enemy>)> ``` Currently, only the first invalid parameter is displayed. Warnings can be disabled on function systems using `.param_never_warn()`. (there is also `.with_param_warn_policy(policy)`) ## Testing Ran `fallible_params` example. --------- Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
…ia the GLOBAL_ERROR_HANDLER (#18454) # Objective There are two related problems here: 1. Users should be able to change the fallback behavior of *all* ECS-based errors in their application by setting the `GLOBAL_ERROR_HANDLER`. See #18351 for earlier work in this vein. 2. The existing solution (#15500) for customizing this behavior is high on boilerplate, not global and adds a great deal of complexity. The consensus is that the default behavior when a parameter fails validation should be set based on the kind of system parameter in question: `Single` / `Populated` should silently skip the system, but `Res` should panic. Setting this behavior at the system level is a bandaid that makes getting to that ideal behavior more painful, and can mask real failures (if a resource is missing but you've ignored a system to make the Single stop panicking you're going to have a bad day). ## Solution I've removed the existing `ParamWarnPolicy`-based configuration, and wired up the `GLOBAL_ERROR_HANDLER`/`default_error_handler` to the various schedule executors to properly plumb through errors . Additionally, I've done a small cleanup pass on the corresponding example. ## Testing I've run the `fallible_params` example, with both the default and a custom global error handler. The former panics (as expected), and the latter spams the error console with warnings 🥲 ## Questions for reviewers 1. Currently, failed system param validation will result in endless console spam. Do you want me to implement a solution for warn_once-style debouncing somehow? 2. Currently, the error reporting for failed system param validation is very limited: all we get is that a system param failed validation and the name of the system. Do you want me to implement improved error reporting by bubbling up errors in this PR? 3. There is broad consensus that the default behavior for failed system param validation should be set on a per-system param basis. Would you like me to implement that in this PR? My gut instinct is that we absolutely want to solve 2 and 3, but it will be much easier to do that work (and review it) if we split the PRs apart. ## Migration Guide `ParamWarnPolicy` and the `WithParamWarnPolicy` have been removed completely. Failures during system param validation are now handled via the `GLOBAL_ERROR_HANDLER`: please see the `bevy_ecs::error` module docs for more information. --------- Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
…ia the GLOBAL_ERROR_HANDLER (#18454) There are two related problems here: 1. Users should be able to change the fallback behavior of *all* ECS-based errors in their application by setting the `GLOBAL_ERROR_HANDLER`. See #18351 for earlier work in this vein. 2. The existing solution (#15500) for customizing this behavior is high on boilerplate, not global and adds a great deal of complexity. The consensus is that the default behavior when a parameter fails validation should be set based on the kind of system parameter in question: `Single` / `Populated` should silently skip the system, but `Res` should panic. Setting this behavior at the system level is a bandaid that makes getting to that ideal behavior more painful, and can mask real failures (if a resource is missing but you've ignored a system to make the Single stop panicking you're going to have a bad day). I've removed the existing `ParamWarnPolicy`-based configuration, and wired up the `GLOBAL_ERROR_HANDLER`/`default_error_handler` to the various schedule executors to properly plumb through errors . Additionally, I've done a small cleanup pass on the corresponding example. I've run the `fallible_params` example, with both the default and a custom global error handler. The former panics (as expected), and the latter spams the error console with warnings 🥲 1. Currently, failed system param validation will result in endless console spam. Do you want me to implement a solution for warn_once-style debouncing somehow? 2. Currently, the error reporting for failed system param validation is very limited: all we get is that a system param failed validation and the name of the system. Do you want me to implement improved error reporting by bubbling up errors in this PR? 3. There is broad consensus that the default behavior for failed system param validation should be set on a per-system param basis. Would you like me to implement that in this PR? My gut instinct is that we absolutely want to solve 2 and 3, but it will be much easier to do that work (and review it) if we split the PRs apart. `ParamWarnPolicy` and the `WithParamWarnPolicy` have been removed completely. Failures during system param validation are now handled via the `GLOBAL_ERROR_HANDLER`: please see the `bevy_ecs::error` module docs for more information. --------- Co-authored-by: MiniaczQ <xnetroidpl@gmail.com>
Objective
System param validation warnings should be configurable and default to "warn once" (per system).
Fixes: #15391
Solution
SystemMetais given a newParamWarnPolicyfield.The policy decides whether warnings will be emitted by each system param when it fails validation.
The policy is updated by the system after param validation fails.
Example warning:
Currently, only the first invalid parameter is displayed.
Warnings can be disabled on function systems using
.param_never_warn().(there is also
.with_param_warn_policy(policy))Testing
Ran
fallible_paramsexample.