From cba9bcc7ba8c7b5b41491e79b30939c9d2f4889f Mon Sep 17 00:00:00 2001 From: dataphract Date: Mon, 7 Mar 2022 09:09:24 +0000 Subject: [PATCH] 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. --- .../bevy_render/src/render_graph/context.rs | 14 +++++------ .../bevy_render/src/render_graph/node_slot.rs | 15 +++++++++++- crates/bevy_render/src/renderer/mod.rs | 23 +++++++++++++++---- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/crates/bevy_render/src/render_graph/context.rs b/crates/bevy_render/src/render_graph/context.rs index ec300ac25e..21b63500bc 100644 --- a/crates/bevy_render/src/render_graph/context.rs +++ b/crates/bevy_render/src/render_graph/context.rs @@ -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, diff --git a/crates/bevy_render/src/render_graph/node_slot.rs b/crates/bevy_render/src/render_graph/node_slot.rs index 471322c0db..fa8aa70e31 100644 --- a/crates/bevy_render/src/render_graph/node_slot.rs +++ b/crates/bevy_render/src/render_graph/node_slot.rs @@ -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)] diff --git a/crates/bevy_render/src/renderer/mod.rs b/crates/bevy_render/src/renderer/mod.rs index dc3f2d244b..2789ef51c8 100644 --- a/crates/bevy_render/src/renderer/mod.rs +++ b/crates/bevy_render/src/renderer/mod.rs @@ -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::(); let render_device = world.resource::(); let render_queue = world.resource::(); - 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();