Skip to content
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

Make AssetLoader/Saver Error type bounds compatible with anyhow::Error #10493

Merged
merged 1 commit into from
Nov 14, 2023

Conversation

rafalh
Copy link
Contributor

@rafalh rafalh commented Nov 10, 2023

Objective

  • In Bevy 0.11 asset loaders used anyhow::Error for returning errors. In Bevy 0.12 AssetLoader (and AssetSaver) have associated Error type. Unfortunately it's type bounds does not allow anyhow::Error to be used despite migration guide claiming otherwise. This makes migration to 0.12 more challenging. Solve this by changing type bounds for associated Error type.
  • Fix Can't use anyhow when writing custom AssetLoaders or AssetSavers #10350

Solution

Change associated Error type bounds to require Into<Box<dyn std::error::Error + Send + Sync + 'static>> to be implemented instead of std::error::Error + Send + Sync + 'static. Both anyhow::Error and errors generated by thiserror seems to be fine with such type bound.


Changelog

Fixed

  • Fixed compatibility with anyhow::Error in AssetLoader and AssetSaver associated Error type

@rafalh
Copy link
Contributor Author

rafalh commented Nov 10, 2023

Code below compiles so I assume it is compatible with pretty much all error types. It would be nice if we could get this change into Bevy 0.12.1 to make migration from 0.11 easier.

trait MyTrait {
    type Error: Into<Box<dyn std::error::Error + Send + Sync + 'static>>;
}

#[derive(Error, Debug)]
pub enum ThisErrorError {
    #[error("Foo")]
    _Foo,
}

#[derive(Debug)]
struct CustomError;
impl std::error::Error for CustomError {}
impl std::fmt::Display for CustomError {
    fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        todo!()
    }
}

struct MyStructWithAnyhowError;
impl MyTrait for MyStructWithAnyhowError {
    type Error = anyhow::Error;
}

struct MyStructWithThiserrorError;
impl MyTrait for MyStructWithThiserrorError {
    type Error = ThisErrorError;
}

struct MyStructWithCustomError;
impl MyTrait for MyStructWithCustomError {
    type Error = CustomError;
}

@rafalh rafalh changed the title Make AssetLoader/Saver Error type bounds compatible with anyhow Make AssetLoader/Saver Error type bounds compatible with anyhow::Error Nov 10, 2023
anyhow::Error does not implement std::error::Error but converting to boxed
std::error::Error is possible. At the same time this bound should work fine
with custom error types like ones generated by thiserror.
Note: after this change Bevy 0.12 migration guide claim that anyhow::Error
works in this context becomes true.
Fixes bevyengine#10350
@nicopap nicopap added this to the 0.13 milestone Nov 10, 2023
@nicopap nicopap added C-Feature A new feature, making something new possible A-Assets Load files from disk to use for things like images, models, and sounds labels Nov 10, 2023
@nicopap nicopap modified the milestones: 0.13, 0.12.1 Nov 10, 2023
@nicopap nicopap added P-Regression Functionality that used to work but no longer does. Add a test for this! and removed C-Feature A new feature, making something new possible labels Nov 10, 2023
@nicopap nicopap removed this from the 0.12.1 milestone Nov 10, 2023
@nicopap
Copy link
Contributor

nicopap commented Nov 10, 2023

I'm not sure I understand this comment:

I also stepped onto this problem. I wanted to use Box<dyn std::error::Error + Send + Sync> as mentioned above but it does not work because T must be Sized for Box<T> to implement std::error::Error which is a little non-intuitive.

What are the implications for this PR?

to reviewers: the relevant std trait impl is: https://doc.rust-lang.org/stable/std/convert/trait.From.html#impl-From%3CE%3E-for-Box%3Cdyn+Error+%2B+Sync+%2B+Send+%2B+'a,+Global%3E

Copy link
Contributor

@nicopap nicopap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me. Would this break compatibility with people using type Error = Box<dyn Error + Send + Sync> as error type?

@rafalh
Copy link
Contributor Author

rafalh commented Nov 10, 2023

I'm not sure I understand this comment:

I also stepped onto this problem. I wanted to use Box<dyn std::error::Error + Send + Sync> as mentioned above but it does not work because T must be Sized for Box<T> to implement std::error::Error which is a little non-intuitive.

What are the implications for this PR?

I wrote this comment before preparing this PR and it is not directly related. It was about workaround proposed in #10350 that does not work (it did not involve anyhow::Error at all). I was trying to understand why it does not work and described my findings.

This makes sense to me. Would this break compatibility with people using type Error = Box<dyn Error + Send + Sync> as error type?

AFAIK there are no such people because Box<dyn Error + Send + Sync> does not implement std::error::Error (which is required by AssetLoader::Error) because of implicit Sized bound in https://doc.rust-lang.org/src/alloc/boxed.rs.html#2433 (dyn Error + Send + Sync is not Sized). It would work if impl<T: core::error::Error + ?Sized> core::error::Error for Box<T> existed.

@nicopap
Copy link
Contributor

nicopap commented Nov 10, 2023

Yeah then I think we can include it in 0.12.1.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Nov 10, 2023
@cart cart added this pull request to the merge queue Nov 14, 2023
Merged via the queue into bevyengine:main with commit e3a59c4 Nov 14, 2023
25 checks passed
Shatur pushed a commit to projectharmonia/bevy that referenced this pull request Nov 19, 2023
bevyengine#10493)

# Objective

* In Bevy 0.11 asset loaders used `anyhow::Error` for returning errors.
In Bevy 0.12 `AssetLoader` (and `AssetSaver`) have associated `Error`
type. Unfortunately it's type bounds does not allow `anyhow::Error` to
be used despite migration guide claiming otherwise. This makes migration
to 0.12 more challenging. Solve this by changing type bounds for
associated `Error` type.
* Fix bevyengine#10350

## Solution

Change associated `Error` type bounds to require `Into<Box<dyn
std::error::Error + Send + Sync + 'static>>` to be implemented instead
of `std::error::Error + Send + Sync + 'static`. Both `anyhow::Error` and
errors generated by `thiserror` seems to be fine with such type bound.

---

## Changelog

### Fixed
* Fixed compatibility with `anyhow::Error` in `AssetLoader` and
`AssetSaver` associated `Error` type
cart pushed a commit that referenced this pull request Nov 30, 2023
#10493)

# Objective

* In Bevy 0.11 asset loaders used `anyhow::Error` for returning errors.
In Bevy 0.12 `AssetLoader` (and `AssetSaver`) have associated `Error`
type. Unfortunately it's type bounds does not allow `anyhow::Error` to
be used despite migration guide claiming otherwise. This makes migration
to 0.12 more challenging. Solve this by changing type bounds for
associated `Error` type.
* Fix #10350

## Solution

Change associated `Error` type bounds to require `Into<Box<dyn
std::error::Error + Send + Sync + 'static>>` to be implemented instead
of `std::error::Error + Send + Sync + 'static`. Both `anyhow::Error` and
errors generated by `thiserror` seems to be fine with such type bound.

---

## Changelog

### Fixed
* Fixed compatibility with `anyhow::Error` in `AssetLoader` and
`AssetSaver` associated `Error` type
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
bevyengine#10493)

# Objective

* In Bevy 0.11 asset loaders used `anyhow::Error` for returning errors.
In Bevy 0.12 `AssetLoader` (and `AssetSaver`) have associated `Error`
type. Unfortunately it's type bounds does not allow `anyhow::Error` to
be used despite migration guide claiming otherwise. This makes migration
to 0.12 more challenging. Solve this by changing type bounds for
associated `Error` type.
* Fix bevyengine#10350

## Solution

Change associated `Error` type bounds to require `Into<Box<dyn
std::error::Error + Send + Sync + 'static>>` to be implemented instead
of `std::error::Error + Send + Sync + 'static`. Both `anyhow::Error` and
errors generated by `thiserror` seems to be fine with such type bound.

---

## Changelog

### Fixed
* Fixed compatibility with `anyhow::Error` in `AssetLoader` and
`AssetSaver` associated `Error` type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds P-Regression Functionality that used to work but no longer does. Add a test for this! S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't use anyhow when writing custom AssetLoaders or AssetSavers
5 participants