1+ use std:: panic:: AssertUnwindSafe ;
2+
13use bevy_tasks:: { ComputeTaskPool , Scope , TaskPool } ;
24use bevy_utils:: default;
35use bevy_utils:: syncunsafecell:: SyncUnsafeCell ;
@@ -167,7 +169,7 @@ impl SystemExecutor for MultiThreadedExecutor {
167169 . receiver
168170 . recv ( )
169171 . await
170- . unwrap_or_else ( |error| unreachable ! ( "{}" , error ) ) ;
172+ . expect ( "A system has panicked so the executor cannot continue." ) ;
171173
172174 self . finish_system_and_signal_dependents ( index) ;
173175
@@ -414,14 +416,22 @@ impl MultiThreadedExecutor {
414416 let task = async move {
415417 #[ cfg( feature = "trace" ) ]
416418 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+ } ) ) ;
419423 #[ cfg( feature = "trace" ) ]
420424 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+ }
425435 } ;
426436
427437 #[ cfg( feature = "trace" ) ]
@@ -463,13 +473,21 @@ impl MultiThreadedExecutor {
463473 let task = async move {
464474 #[ cfg( feature = "trace" ) ]
465475 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+ } ) ) ;
467479 #[ cfg( feature = "trace" ) ]
468480 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+ }
473491 } ;
474492
475493 #[ cfg( feature = "trace" ) ]
@@ -479,13 +497,21 @@ impl MultiThreadedExecutor {
479497 let task = async move {
480498 #[ cfg( feature = "trace" ) ]
481499 let system_guard = system_span. enter ( ) ;
482- system. run ( ( ) , world) ;
500+ let res = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
501+ system. run ( ( ) , world) ;
502+ } ) ) ;
483503 #[ cfg( feature = "trace" ) ]
484504 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+ }
489515 } ;
490516
491517 #[ cfg( feature = "trace" ) ]
0 commit comments