bevy icon indicating copy to clipboard operation
bevy copied to clipboard

allow access to the source error of `AssetLoaderError` and downcasting

Open Austreelis opened this issue 7 months ago • 3 comments

Objective

I have a custom asset loader, and need access to the error it reports when failing to load (e.g. through AssetLoadFailedEvent { error: AssetLoadError::AssetLoaderError(loader_error), .. }). However AssetLoaderError doesn't expose its <core::error::Error>::source() (i.e. its error field. It only formats it when Displayed.

I haven't searched for issues about it.

Solution

  • Annotate AssetLoaderError's error field with #[source].
  • Don't include the error when AssetLoaderError is Displayed (when one prints an error's source stack like a backtrace, it would now be dupplicated).
  • (optional, included as a separated commit) Add a getter for the &dyn Error stored in the error field (whithin an Arc). This is more ergonomic than using Error::source() because it casts an &Arc<dyn Error> into an &dyn Error, meaning one has to downcast it twice to get the original error from the loader, including once where you have to specify the correct type of the private error field. So downcasting from Error::source() effectively rely on the internal implementation of AssetLoaderError. The getter instead return the trait object directly, which mean it will directly downcast to the expected loader error type.

I didn't included a test that checks that double-downcasting <AssetLoaderError as Error>::source() doesn't break user code that would rely on the private field's type.

Testing

  • Downcasting the trait objects for both source() and the error() getter work as described above.
  • cargo test -p bevy_asset --all-features pass without errors.

Austreelis avatar Jun 02 '25 20:06 Austreelis

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

github-actions[bot] avatar Jun 02 '25 20:06 github-actions[bot]

Oh this broke the test error_on_nested_immediate_load_of_subasset because it partly did what this PR tries to fix: It checks that we indeed get an error from the loader but cannot access it, so it matches the error message. I added a commit to fix it, now it downcasts the error and panics if it's not the underlying <_ as AssetLoader>::Error. It still checks that the error message mentions that nested immediate loads of subassets are unsupported though.

Austreelis avatar Jun 02 '25 23:06 Austreelis

I expected the conflict, I'll get around that tomorrow now :)

Austreelis avatar Jun 04 '25 00:06 Austreelis

  • rebased :3
  • I've removed the forwarding of the inner error through coore::error::Error::source() because #19478 made it a BevyError which doesn't implements the trait. So the only change is the addition of a getter for it.
  • cargo run -p ci -- lints failed locally but it seemed unrelated ? Unsure if I should do something about it here.

Austreelis avatar Jun 05 '25 16:06 Austreelis

This is still failing CI. I think it might be relevant? It's from server/mod.rs.

andriyDev avatar Jun 06 '25 20:06 andriyDev