1
+ use std:: panic:: AssertUnwindSafe ;
2
+
1
3
use bevy_tasks:: { ComputeTaskPool , Scope , TaskPool } ;
2
4
use bevy_utils:: default;
3
5
use bevy_utils:: syncunsafecell:: SyncUnsafeCell ;
@@ -167,7 +169,7 @@ impl SystemExecutor for MultiThreadedExecutor {
167
169
. receiver
168
170
. recv ( )
169
171
. await
170
- . unwrap_or_else ( |error| unreachable ! ( "{}" , error ) ) ;
172
+ . expect ( "A system has panicked so the executor cannot continue." ) ;
171
173
172
174
self . finish_system_and_signal_dependents ( index) ;
173
175
@@ -414,14 +416,22 @@ impl MultiThreadedExecutor {
414
416
let task = async move {
415
417
#[ cfg( feature = "trace" ) ]
416
418
let system_guard = system_span. enter ( ) ;
417
- // SAFETY: access is compatible
418
- unsafe { system. run_unsafe ( ( ) , world) } ;
419
+ let res = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
420
+ // SAFETY: access is compatible
421
+ unsafe { system. run_unsafe ( ( ) , world) } ;
422
+ } ) ) ;
419
423
#[ cfg( feature = "trace" ) ]
420
424
drop ( system_guard) ;
421
- sender
422
- . send ( system_index)
423
- . await
424
- . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
425
+ if res. is_err ( ) {
426
+ // close the channel to propagate the error to the
427
+ // multithreaded executor
428
+ sender. close ( ) ;
429
+ } else {
430
+ sender
431
+ . send ( system_index)
432
+ . await
433
+ . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
434
+ }
425
435
} ;
426
436
427
437
#[ cfg( feature = "trace" ) ]
@@ -463,13 +473,21 @@ impl MultiThreadedExecutor {
463
473
let task = async move {
464
474
#[ cfg( feature = "trace" ) ]
465
475
let system_guard = system_span. enter ( ) ;
466
- apply_system_buffers ( & mut unapplied_systems, systems, world) ;
476
+ let res = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
477
+ apply_system_buffers ( & mut unapplied_systems, systems, world) ;
478
+ } ) ) ;
467
479
#[ cfg( feature = "trace" ) ]
468
480
drop ( system_guard) ;
469
- sender
470
- . send ( system_index)
471
- . await
472
- . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
481
+ if res. is_err ( ) {
482
+ // close the channel to propagate the error to the
483
+ // multithreaded executor
484
+ sender. close ( ) ;
485
+ } else {
486
+ sender
487
+ . send ( system_index)
488
+ . await
489
+ . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
490
+ }
473
491
} ;
474
492
475
493
#[ cfg( feature = "trace" ) ]
@@ -479,13 +497,21 @@ impl MultiThreadedExecutor {
479
497
let task = async move {
480
498
#[ cfg( feature = "trace" ) ]
481
499
let system_guard = system_span. enter ( ) ;
482
- system. run ( ( ) , world) ;
500
+ let res = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
501
+ system. run ( ( ) , world) ;
502
+ } ) ) ;
483
503
#[ cfg( feature = "trace" ) ]
484
504
drop ( system_guard) ;
485
- sender
486
- . send ( system_index)
487
- . await
488
- . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
505
+ if res. is_err ( ) {
506
+ // close the channel to propagate the error to the
507
+ // multithreaded executor
508
+ sender. close ( ) ;
509
+ } else {
510
+ sender
511
+ . send ( system_index)
512
+ . await
513
+ . unwrap_or_else ( |error| unreachable ! ( "{}" , error) ) ;
514
+ }
489
515
} ;
490
516
491
517
#[ cfg( feature = "trace" ) ]
0 commit comments