Skip to content

Commit 4c87867

Browse files
committed
report a command system origin in case of panic
1 parent 3c96131 commit 4c87867

File tree

6 files changed

+36
-4
lines changed

6 files changed

+36
-4
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ trace_chrome = ["bevy_internal/trace_chrome"]
5252
trace = ["bevy_internal/trace"]
5353
wgpu_trace = ["bevy_internal/wgpu_trace"]
5454

55+
bevy_command_panic_origin = ["bevy_internal/bevy_command_panic_origin"]
56+
5557
# Image format support for texture loading (PNG and HDR are enabled by default)
5658
hdr = ["bevy_internal/hdr"]
5759
png = ["bevy_internal/png"]

crates/bevy_ecs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ categories = ["game-engines", "data-structures"]
1515

1616
[features]
1717
trace = []
18+
command_panic_origin = []
1819
default = ["bevy_reflect"]
1920

2021
[dependencies]

crates/bevy_ecs/src/system/commands.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ use crate::{
55
world::World,
66
};
77
use bevy_utils::tracing::debug;
8-
use std::marker::PhantomData;
8+
#[cfg(feature = "command_panic_origin")]
9+
use bevy_utils::tracing::error;
10+
#[cfg(feature = "command_panic_origin")]
11+
use std::panic::{self, AssertUnwindSafe};
12+
use std::{borrow::Cow, marker::PhantomData};
913

1014
/// A [`World`] mutation.
1115
pub trait Command: Send + Sync + 'static {
@@ -15,7 +19,9 @@ pub trait Command: Send + Sync + 'static {
1519
/// A queue of [`Command`]s.
1620
#[derive(Default)]
1721
pub struct CommandQueue {
18-
commands: Vec<Box<dyn Command>>,
22+
pub(crate) commands: Vec<Box<dyn Command>>,
23+
#[allow(unused)]
24+
pub(crate) system_name: Option<Cow<'static, str>>,
1925
}
2026

2127
impl CommandQueue {
@@ -24,7 +30,20 @@ impl CommandQueue {
2430
pub fn apply(&mut self, world: &mut World) {
2531
world.flush();
2632
for command in self.commands.drain(..) {
33+
// TODO: replace feature by proper error handling from commands
34+
#[cfg(not(feature = "command_panic_origin"))]
2735
command.write(world);
36+
#[cfg(feature = "command_panic_origin")]
37+
if panic::catch_unwind(AssertUnwindSafe(|| {
38+
command.write(world);
39+
}))
40+
.is_err()
41+
{
42+
if let Some(system_name) = &self.system_name {
43+
error!("panic while applying a command from {}", system_name);
44+
}
45+
panic!("panic applying a command");
46+
}
2847
}
2948
}
3049

crates/bevy_ecs/src/system/into_system.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ impl SystemState {
4747
pub fn set_non_send(&mut self) {
4848
self.is_send = false;
4949
}
50+
51+
pub fn name(&self) -> Cow<'static, str> {
52+
self.name.clone()
53+
}
5054
}
5155

5256
/// Conversion trait to turn something into a [`System`].

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,11 @@ impl<'a> SystemParam for Commands<'a> {
529529
unsafe impl SystemParamState for CommandQueue {
530530
type Config = ();
531531

532-
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
533-
Default::default()
532+
fn init(_world: &mut World, system_state: &mut SystemState, _config: Self::Config) -> Self {
533+
CommandQueue {
534+
system_name: Some(system_state.name()),
535+
..Default::default()
536+
}
534537
}
535538

536539
fn apply(&mut self, world: &mut World) {

crates/bevy_internal/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ x11 = ["bevy_winit/x11"]
4141
# enable rendering of font glyphs using subpixel accuracy
4242
subpixel_glyph_atlas = ["bevy_text/subpixel_glyph_atlas"]
4343

44+
# enable tracing system origin of commands in case of command failure
45+
bevy_command_panic_origin = ["bevy_ecs/command_panic_origin"]
46+
4447
# enable systems that allow for automated testing on CI
4548
bevy_ci_testing = ["bevy_app/bevy_ci_testing"]
4649

0 commit comments

Comments
 (0)