improve error messages for render graph runner (#3930)

# Objective

Currently, errors in the render graph runner are exposed via a `Result::unwrap()` panic message, which dumps the debug representation of the error.

## Solution

This PR updates `render_system` to log the chain of errors, followed by an explicit panic:

```
ERROR bevy_render::renderer: Error running render graph:
ERROR bevy_render::renderer: > encountered an error when running a sub-graph
ERROR bevy_render::renderer: > tried to pass inputs to sub-graph "outline_graph", which has no input slots
thread 'main' panicked at 'Error running render graph: encountered an error when running a sub-graph', /[redacted]/bevy/crates/bevy_render/src/renderer/mod.rs:44:9
```

Some errors' `Display` impls (via `thiserror`) have also been updated to provide more detail about the cause of the error.
This commit is contained in:
dataphract 2022-03-07 09:09:24 +00:00
parent 159fe527a8
commit cba9bcc7ba
3 changed files with 40 additions and 12 deletions

View file

@ -207,11 +207,11 @@ impl<'a> RenderGraphContext<'a> {
#[derive(Error, Debug, Eq, PartialEq)]
pub enum RunSubGraphError {
#[error("tried to run a non-existent sub-graph")]
#[error("attempted to run sub-graph `{0}`, but it does not exist")]
MissingSubGraph(Cow<'static, str>),
#[error("passed in inputs, but this sub-graph doesn't have any")]
#[error("attempted to pass inputs to sub-graph `{0}`, which has no input slots")]
SubGraphHasNoInputs(Cow<'static, str>),
#[error("sub graph (name: '{graph_name:?}') could not be run because slot '{slot_name}' at index {slot_index} has no value")]
#[error("sub graph (name: `{graph_name:?}`) could not be run because slot `{slot_name}` at index {slot_index} has no value")]
MissingInput {
slot_index: usize,
slot_name: Cow<'static, str>,
@ -229,9 +229,9 @@ pub enum RunSubGraphError {
#[derive(Error, Debug, Eq, PartialEq)]
pub enum OutputSlotError {
#[error("slot does not exist")]
#[error("output slot `{0:?}` does not exist")]
InvalidSlot(SlotLabel),
#[error("attempted to assign the wrong type to slot")]
#[error("attempted to output a value of type `{actual}` to output slot `{label:?}`, which has type `{expected}`")]
MismatchedSlotType {
label: SlotLabel,
expected: SlotType,
@ -241,9 +241,9 @@ pub enum OutputSlotError {
#[derive(Error, Debug, Eq, PartialEq)]
pub enum InputSlotError {
#[error("slot does not exist")]
#[error("input slot `{0:?}` does not exist")]
InvalidSlot(SlotLabel),
#[error("attempted to retrieve the wrong type from input slot")]
#[error("attempted to retrieve a value of type `{actual}` from input slot `{label:?}`, which has type `{expected}`")]
MismatchedSlotType {
label: SlotLabel,
expected: SlotType,

View file

@ -1,5 +1,5 @@
use bevy_ecs::entity::Entity;
use std::borrow::Cow;
use std::{borrow::Cow, fmt};
use crate::render_resource::{Buffer, Sampler, TextureView};
@ -74,6 +74,19 @@ pub enum SlotType {
Entity,
}
impl fmt::Display for SlotType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
SlotType::Buffer => "Buffer",
SlotType::TextureView => "TextureView",
SlotType::Sampler => "Sampler",
SlotType::Entity => "Entity",
};
f.write_str(s)
}
}
/// A [`SlotLabel`] is used to reference a slot by either its name or index
/// inside the [`RenderGraph`](super::RenderGraph).
#[derive(Debug, Clone, Eq, PartialEq)]

View file

@ -1,7 +1,7 @@
mod graph_runner;
mod render_device;
use bevy_utils::tracing::{info, info_span};
use bevy_utils::tracing::{error, info, info_span};
pub use graph_runner::*;
pub use render_device::*;
@ -22,13 +22,28 @@ pub fn render_system(world: &mut World) {
let graph = world.resource::<RenderGraph>();
let render_device = world.resource::<RenderDevice>();
let render_queue = world.resource::<RenderQueue>();
RenderGraphRunner::run(
if let Err(e) = RenderGraphRunner::run(
graph,
render_device.clone(), // TODO: is this clone really necessary?
render_queue,
world,
)
.unwrap();
) {
error!("Error running render graph:");
{
let mut src: &dyn std::error::Error = &e;
loop {
error!("> {}", src);
match src.source() {
Some(s) => src = s,
None => break,
}
}
}
panic!("Error running render graph: {}", e);
}
{
let span = info_span!("present_frames");
let _guard = span.enter();