Mention Option and When in the error message for a failing system parameter (#19490)

# Objective

Help users discover how to use `Option<T>` and `When<T>` to handle
failing parameters.

## Solution

Have the error message for a failed parameter mention that `Option<T>`
and `When<T>` can be used to handle the failure.

## Showcase

```
Encountered an error in system `system_name`: Parameter `Res<ResourceType>` failed validation: Resource does not exist
If this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `When<T>` to skip the system when it happens.
```
This commit is contained in:
Chris Russell 2025-06-04 12:39:54 -04:00 committed by GitHub
parent 6fee6fe827
commit bd4c960f26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 8 additions and 4 deletions

View File

@ -456,7 +456,7 @@ mod tests {
let result = world.run_system_once(system); let result = world.run_system_once(system);
assert!(matches!(result, Err(RunSystemError::InvalidParams { .. }))); assert!(matches!(result, Err(RunSystemError::InvalidParams { .. })));
let expected = "System bevy_ecs::system::system::tests::run_system_once_invalid_params::system did not run due to failed parameter validation: Parameter `Res<T>` failed validation: Resource does not exist"; let expected = "System bevy_ecs::system::system::tests::run_system_once_invalid_params::system did not run due to failed parameter validation: Parameter `Res<T>` failed validation: Resource does not exist\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `When<T>` to skip the system when it happens.";
assert_eq!(expected, result.unwrap_err().to_string()); assert_eq!(expected, result.unwrap_err().to_string());
} }
} }

View File

@ -151,7 +151,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
/// let mut world = World::new(); /// let mut world = World::new();
/// let err = world.run_system_cached(|param: MyParam| {}).unwrap_err(); /// let err = world.run_system_cached(|param: MyParam| {}).unwrap_err();
/// let expected = "Parameter `MyParam::foo` failed validation: Custom Message"; /// let expected = "Parameter `MyParam::foo` failed validation: Custom Message";
/// assert!(err.to_string().ends_with(expected)); /// assert!(err.to_string().contains(expected));
/// ``` /// ```
/// ///
/// ## Builders /// ## Builders
@ -2557,7 +2557,11 @@ impl Display for SystemParamValidationError {
ShortName(&self.param), ShortName(&self.param),
self.field, self.field,
self.message self.message
) )?;
if !self.skipped {
write!(fmt, "\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `When<T>` to skip the system when it happens.")?;
}
Ok(())
} }
} }

View File

@ -880,7 +880,7 @@ mod tests {
result, result,
Err(RegisteredSystemError::InvalidParams { .. }) Err(RegisteredSystemError::InvalidParams { .. })
)); ));
let expected = format!("System {id:?} did not run due to failed parameter validation: Parameter `Res<T>` failed validation: Resource does not exist"); let expected = format!("System {id:?} did not run due to failed parameter validation: Parameter `Res<T>` failed validation: Resource does not exist\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `When<T>` to skip the system when it happens.");
assert_eq!(expected, result.unwrap_err().to_string()); assert_eq!(expected, result.unwrap_err().to_string());
} }