- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.2k
Description
Bevy version
- 0.10.1
- 0.11.0-dev
- main branch, commit 25f013b
What you did
Attach warn to a system that would return a result:
// Using bevy 0.11.0-dev, main branch commit 25f013b in this example
use bevy::{log::LogPlugin, prelude::*};
fn main() {
    App::new()
        .add_plugin(LogPlugin::default())
        .add_systems(Startup, where_result_system_is::result_system.pipe(warn))
        .run();
}
pub mod where_result_system_is {
    pub fn result_system() -> Result<(), String> {
        Err("Error returned by system".to_owned())
    }
}What went wrong
I expected to get information about where the error was generated from, i.e.
# Desired result
# The module path points to where the result system is located.
WARN my_project::where_result_system_is: "Error returned by system"Instead, I only get the module location of warn:
# Actual result
# The module path instead points to the bevy `warn` adaptor, reducing its 
# usefulness as an approach to error logging.
WARN bevy_ecs::system::system_piping::adapter: "Error returned by system"Additional information
Discussed in #8637
Originally posted by fallible-algebra May 19, 2023
I've been working on a bevy project for a couple of months and have come across a minor information hiccup with error logging.
When using system piping for error logging, the results the system return will get reported by the logging suite as coming from the wrapper system (i.e. warn or info) rather than the function that returned the error i.e. as a stripped down version of this example
fn main() {
    App::new()
    // ...
    .add_system(result_system.pipe(warn)
    .run();
}
pub mod where_result_system_is {
    pub fn result_system(/* whatever inputs */) -> Result<(), String> {
        Err("Error returned by system".to_owned())
    }
}# Actual output, shows the path to where `warn` is defined.
WARN bevy_ecs::system::system_piping::adapter: Error returned by system
# Desired output, shows the path to where `result_system` is defined.
WARN my_project::where_result_system_is: Error returned by systemThe latter is desired as it gives me information as to where the warning is actually coming from, and my project has a wide and deep directory tree.
I'm aware this is behaviour to be expected from using the logging suite + the system piping interfaces together, but this is suboptimal from a point of view of using system piping for error logging. Is there a macro-based approach someone else has worked on? Something that transforms a system that returns a result into a system that doesn't return a result that matches on the result in-function-body, i.e.
#[system_result_transform_macro_of_some_kind(warn)]
pub fn result_system(/* whatever inputs */) -> Result<(), String> {
    Err("Error returned by system")
}
// Becomes
pub fn result_system(/* whatever inputs */) {
    // Or however else the body needs to be encapsulated to allow i.e. ? syntax.
    let res = {Err("Error returned by system")};
    match res {
        Ok(()) => {},
        Err(err) => warn!(err)
    }
}
// So that error location is preserved.Or is there something else I should be relying on, have I missed something obvious, or is this all splitting hairs? Thanks.
I want to be clear that I don't presume that warn (the adaptor) can be capable of getting this information, that it is correct to pursue a solution where warn can receive that information, or that the macro solution is necessarily correct either.
I am aware this is a limitation on using system piping as error logging, but it was the direction I was pointed in for being able to handle errors in systems via results and ?s instead of unwraps and expects and logging in-systems and I'm losing logging information on a project with a broad and deep structure via this method.
Thanks for continuing to develop bevy.