Skip to content

Replace unwraps with expects in bevy_app, bevy_audio, bevy_core, and bevy_core_pipeline #3913

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

Closed
wants to merge 12 commits into from

Conversation

tyleranton
Copy link

@tyleranton tyleranton commented Feb 10, 2022

Objective

Solution

  • Provide somewhat more helpful error messages by replacing unwraps with expects.

Meta

This is my first time contributing and really looking at the code base, so I wasn't completely confident in all of my expect error messages. Feedback is welcome and appreciated!

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label Feb 10, 2022
Copy link
Contributor

@Ixentus Ixentus left a comment

Choose a reason for hiding this comment

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

Looks good. Just some nits.

@ghost ghost mentioned this pull request Feb 11, 2022
31 tasks
@IceSentry IceSentry added C-Code-Quality A section of code that is hard to understand or change C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed S-Needs-Triage This issue needs to be labelled labels Feb 11, 2022
@tyleranton
Copy link
Author

Is amending commits okay here since it's simple, or are new commits preferred? Thanks for taking time to review this!

@ghost
Copy link

ghost commented Feb 11, 2022

That shouldn't really matter. The fastest way to commit the suggested changes is to use the commit suggestion button directly below the suggestion. This will create new commits, which is the way I saw it being done most of the time. Feel free to use whatever method is more convenient for you. For bigger changes I would prefer a new commit though.

Comment on lines +78 to +83
let audio_output = world
.get_non_send::<AudioOutput<Source>>()
.expect("Could not find `AudioOutput` in the `World`.");
let mut audio = world
.get_resource_mut::<Audio<Source>>()
.expect("Could not find `Audio` in the `World`.");
Copy link
Member

Choose a reason for hiding this comment

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

In both those cases, the issue would be either:

  • the user is calling this system without adding the AudioPlugin
  • the user is calling this system on a custom Source without having it set up first like in
    app.init_non_send_resource::<AudioOutput<AudioSource>>()
    .add_asset::<AudioSource>()
    .init_resource::<Audio<AudioSource>>()

It could be helpful to explain how to fix the issue

Copy link
Author

Choose a reason for hiding this comment

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

Would this be a case where adding to the error codes is best for an explanation?

@tyleranton
Copy link
Author

Just wanted to bump this for further review
@mockersf @Ixentus @KDecay

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

Did a pass over everything. I think you might be missing some unwraps. For example in the bevy_core_pipeline there is an unwrap() that didn't get addressed. Could you do a second pass over the crates and see if you find any more unwraps that should be changed? Thank you <3

0,
*world
.get_resource::<Count>()
.expect("Could not find `Count` in the `World`.")
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not find `Count` in the `World`.")
.expect("Could not get the `Count` resource from the `World`")

1,
*world
.get_resource::<Count>()
.expect("Could not find `Count` in the `World`.")
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not find `Count` in the `World`.")
.expect("Could not get the `Count` resource from the `World`")

3,
*world
.get_resource::<Count>()
.expect("Could not find `Count` in the `World`.")
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not find `Count` in the `World`.")
.expect("Could not get the `Count` resource from the `World`")

let draw_functions = world.get_resource::<DrawFunctions<AlphaMask3d>>().unwrap();
let draw_functions = world
.get_resource::<DrawFunctions<AlphaMask3d>>()
.expect("Could not get `DrawFunctions` resource from the `World`.");
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not get `DrawFunctions` resource from the `World`.");
.expect("Could not get the `DrawFunctions<AlphaMask3d>` resource from the `World`. It can be added using the `CorePipelinePlugin`, or the `DefaultPlugins`");

let draw_function = draw_functions.get_mut(item.draw_function).unwrap();
let draw_function = draw_functions
.get_mut(item.draw_function)
.expect("Could not get draw function.");
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not get draw function.");
.unwrap_or_else(|| {
panic!("Could not get the draw function for id: {}", item.draw_function.0);
});

@@ -147,15 +153,17 @@ impl Node for MainPass3dNode {

let draw_functions = world
.get_resource::<DrawFunctions<Transparent3d>>()
.unwrap();
.expect("Could not get `DrawFunctions` resource from the `World`.");
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not get `DrawFunctions` resource from the `World`.");
.expect("Could not get the `DrawFunctions<Transparent3d>` resource from the `World`. It can be added using the `CorePipelinePlugin`, or the `DefaultPlugins`");

let draw_function = draw_functions.get_mut(item.draw_function).unwrap();
let draw_function = draw_functions
.get_mut(item.draw_function)
.expect("Could not get draw function.");
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not get draw function.");
.unwrap_or_else(|| {
panic!("Could not get the draw function for id: {}", item.draw_function.0);
});

let extracted_cameras = world.get_resource::<ExtractedCameraNames>().unwrap();
let extracted_cameras = world
.get_resource::<ExtractedCameraNames>()
.expect("Could not get `ExtractedCameraNames` resource from the `World`.");
Copy link

Choose a reason for hiding this comment

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

Suggested change
.expect("Could not get `ExtractedCameraNames` resource from the `World`.");
.expect("Could not get the `ExtractedCameraNames` resource from the `World`. It can be added using the `CameraPlugin`, `RenderPlugin` or the `DefaultPlugins`");

tyleranton and others added 2 commits February 26, 2022 19:31
@tyleranton
Copy link
Author

tyleranton commented Feb 26, 2022

@KDecay wow thanks for going through all of this. Would committing all of these suggestions separately be too noisy? I know you said it's common to use that feature, just wasn't sure if volume mattered here. Appreciate the review!

Edit: Just saw the request to pause work on the tracking issue, so you can disregard the above. Thanks again!

@ghost
Copy link

ghost commented Feb 27, 2022

@KDecay wow thanks for going through all of this. Would committing all of these suggestions separately be too noisy? I know you said it's common to use that feature, just wasn't sure if volume mattered here. Appreciate the review!

@tylerdotdev You can also combine the small suggestions into one larger commit to reduce noise.

Edit: Just saw the request to pause work on the tracking issue, so you can disregard the above. Thanks again!

Yup, we figured that it would be beneficial to get some of the extremely common cases out of the way first (e.g. failing on getting a resource). This will remove a lot of expects in all of the PR's related to the tracking issue which means that we can focus on the error messages themselves instead of painfully trying to keep everything consistent throughout all of the PR's.

@@ -176,7 +176,7 @@ impl Plugin for CorePipelinePlugin {
draw_3d_graph::node::MAIN_PASS,
MainPass3dNode::IN_VIEW,
)
.unwrap();
.expect("Could not add slot edge to `RenderGraph`.");
Copy link
Member

Choose a reason for hiding this comment

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

Something to consider before throwing expects onto more "internal" non-user facing code: static strings are compiled into the binary. I don't think we want to bloat bevy apps with a bunch of "internal error messages", especially in cases like these where the context of the code is as good (if not better) for debugging than the message in the expect (for a Bevy Engine dev debugging a user-reported error).

@alice-i-cecile
Copy link
Member

Closing per discussion in #3899 <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Code-Quality A section of code that is hard to understand or change C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants