From b9c7c844f133d09f429775120b7626f3505c6191 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Fri, 11 Apr 2025 01:45:15 +0200 Subject: [PATCH 1/5] remove configurable_error_handler feature --- Cargo.toml | 6 +- crates/bevy_ecs/Cargo.toml | 7 -- crates/bevy_ecs/src/error/handler.rs | 108 +++++++++++++-------- crates/bevy_ecs/src/error/mod.rs | 12 +-- crates/bevy_ecs/src/system/commands/mod.rs | 4 +- crates/bevy_internal/Cargo.toml | 3 - docs/cargo_features.md | 1 - examples/ecs/error_handling.rs | 9 +- examples/ecs/fallible_params.rs | 11 +-- 9 files changed, 80 insertions(+), 81 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 04db26208b3dd..edcdbc185f58b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -288,9 +288,6 @@ bevy_remote = ["bevy_internal/bevy_remote"] # Enable input focus subsystem bevy_input_focus = ["bevy_internal/bevy_input_focus"] -# Use the configurable global error handler as the default error handler. -configurable_error_handler = ["bevy_internal/configurable_error_handler"] - # Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation) spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"] @@ -2215,7 +2212,6 @@ wasm = false name = "fallible_params" path = "examples/ecs/fallible_params.rs" doc-scrape-examples = true -required-features = ["configurable_error_handler"] [package.metadata.example.fallible_params] name = "Fallible System Parameters" @@ -2227,7 +2223,7 @@ wasm = false name = "error_handling" path = "examples/ecs/error_handling.rs" doc-scrape-examples = true -required-features = ["bevy_mesh_picking_backend", "configurable_error_handler"] +required-features = ["bevy_mesh_picking_backend"] [package.metadata.example.error_handling] name = "Error handling" diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index 97cdcee0824b7..28987f1413449 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -33,13 +33,6 @@ bevy_reflect = ["dep:bevy_reflect"] ## Extends reflection support to functions. reflect_functions = ["bevy_reflect", "bevy_reflect/functions"] -## Use the configurable global error handler as the default error handler. -## -## This is typically used to turn panics from the ECS into loggable errors. -## This may be useful for production builds, -## but can result in a measurable performance impact, especially for commands. -configurable_error_handler = [] - ## Enables automatic backtrace capturing in BevyError backtrace = ["std"] diff --git a/crates/bevy_ecs/src/error/handler.rs b/crates/bevy_ecs/src/error/handler.rs index 688b599473ab9..3d20a34b6683f 100644 --- a/crates/bevy_ecs/src/error/handler.rs +++ b/crates/bevy_ecs/src/error/handler.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "configurable_error_handler")] -use bevy_platform::sync::OnceLock; use core::fmt::Display; use crate::{component::Tick, error::BevyError}; @@ -77,51 +75,75 @@ impl ErrorContext { } } -/// A global error handler. This can be set at startup, as long as it is set before -/// any uses. This should generally be configured _before_ initializing the app. -/// -/// This should be set inside of your `main` function, before initializing the Bevy app. -/// The value of this error handler can be accessed using the [`default_error_handler`] function, -/// which calls [`OnceLock::get_or_init`] to get the value. -/// -/// **Note:** this is only available when the `configurable_error_handler` feature of `bevy_ecs` (or `bevy`) is enabled! -/// -/// # Example -/// -/// ``` -/// # use bevy_ecs::error::{GLOBAL_ERROR_HANDLER, warn}; -/// GLOBAL_ERROR_HANDLER.set(warn).expect("The error handler can only be set once, globally."); -/// // initialize Bevy App here -/// ``` -/// -/// To use this error handler in your app for custom error handling logic: -/// -/// ```rust -/// use bevy_ecs::error::{default_error_handler, GLOBAL_ERROR_HANDLER, BevyError, ErrorContext, panic}; -/// -/// fn handle_errors(error: BevyError, ctx: ErrorContext) { -/// let error_handler = default_error_handler(); -/// error_handler(error, ctx); -/// } -/// ``` -/// -/// # Warning -/// -/// As this can *never* be overwritten, library code should never set this value. -#[cfg(feature = "configurable_error_handler")] -pub static GLOBAL_ERROR_HANDLER: OnceLock = OnceLock::new(); +mod global_error_handler { + use super::{BevyError, ErrorContext}; + use bevy_platform_support::sync::atomic::{ + AtomicPtr, + Ordering::{AcqRel, Acquire, Relaxed}, + }; + + // SAFETY: Only accessible from within this module. + static HANDLER_ADDRESS: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut()); + + /// Set the global error handler. + /// + /// If used, this should be called [before] any uses of [`default_error_handler`], + /// generally inside your `main` function before initializing the app. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::error::{set_global_default_error_handler, warn}; + /// set_global_default_error_handler(warn); + /// // initialize Bevy App here + /// ``` + /// + /// To use this error handler in your app for custom error handling logic: + /// + /// ```rust + /// use bevy_ecs::error::{default_error_handler, BevyError, ErrorContext, panic}; + /// + /// fn handle_errors(error: BevyError, ctx: ErrorContext) { + /// let error_handler = default_error_handler(); + /// error_handler(error, ctx); + /// } + /// ``` + /// + /// # Warning + /// + /// As this can *never* be overwritten, library code should never set this value. + /// + /// [before]: https://doc.rust-lang.org/nightly/core/sync/atomic/index.html#memory-model-for-atomic-accesses + /// [`default_error_handler`]: super::default_error_handler + pub fn set_global_default_error_handler(handler: fn(BevyError, ErrorContext)) { + if HANDLER_ADDRESS + .compare_exchange(core::ptr::null_mut(), handler as *mut (), AcqRel, Acquire) + .is_err() + { + panic!("Global error handler set multiple times"); + } + } + + #[inline] + pub(super) fn get() -> Option { + // The error handler must have been already set from the perspective of this thread, + // otherwise we will panic. It will never be updated after this point. + // We therefore only need a relaxed load. + let ptr = HANDLER_ADDRESS.load(Relaxed); + // SAFETY: We only ever store null or a valid handler function. + // `null` is guaranteed to be represent `None`: + // https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html#representation + unsafe { core::mem::transmute(ptr) } + } +} + +pub use global_error_handler::set_global_default_error_handler; /// The default error handler. This defaults to [`panic()`], -/// but if set, the [`GLOBAL_ERROR_HANDLER`] will be used instead, enabling error handler customization. -/// The `configurable_error_handler` feature must be enabled to change this from the panicking default behavior, -/// as there may be runtime overhead. +/// but you can override this behavior via [`set_global_error_handler`]. #[inline] pub fn default_error_handler() -> fn(BevyError, ErrorContext) { - #[cfg(not(feature = "configurable_error_handler"))] - return panic; - - #[cfg(feature = "configurable_error_handler")] - return *GLOBAL_ERROR_HANDLER.get_or_init(|| panic); + global_error_handler::get().unwrap_or(panic) } macro_rules! inner { diff --git a/crates/bevy_ecs/src/error/mod.rs b/crates/bevy_ecs/src/error/mod.rs index 950deee3ecf97..f4ac4fa9b7b2b 100644 --- a/crates/bevy_ecs/src/error/mod.rs +++ b/crates/bevy_ecs/src/error/mod.rs @@ -7,8 +7,9 @@ //! All [`BevyError`]s returned by a system, observer or command are handled by an "error handler". By default, the //! [`panic`] error handler function is used, resulting in a panic with the error message attached. //! -//! You can change the default behavior by registering a custom error handler. -//! Modify the [`GLOBAL_ERROR_HANDLER`] value to set a custom error handler function for your entire app. +//! You can change the default behavior by registering a custom error handler: +//! Use [`set_global_default_error_handler`](crate::error::set_global_default_error_handler) +//! to set a custom error handler function for your entire app. //! In practice, this is generally feature-flagged: panicking or loudly logging errors in development, //! and quietly logging or ignoring them in production to avoid crashing the app. //! @@ -33,10 +34,8 @@ //! The [`ErrorContext`] allows you to access additional details relevant to providing //! context surrounding the error – such as the system's [`name`] – in your error messages. //! -//! Remember to turn on the `configurable_error_handler` feature to set a global error handler! -//! //! ```rust, ignore -//! use bevy_ecs::error::{GLOBAL_ERROR_HANDLER, BevyError, ErrorContext}; +//! use bevy_ecs::error::{set_global_error_handler, BevyError, ErrorContext}; //! use log::trace; //! //! fn my_error_handler(error: BevyError, ctx: ErrorContext) { @@ -48,8 +47,7 @@ //! } //! //! fn main() { -//! // This requires the "configurable_error_handler" feature to be enabled to be in scope. -//! GLOBAL_ERROR_HANDLER.set(my_error_handler).expect("The error handler can only be set once."); +//! set_global_error_handler(my_error_handler); //! //! // Initialize your Bevy App here //! } diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 4cb6d61bc0e9a..087a134db8ba8 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -90,7 +90,7 @@ use crate::{ /// which will be passed to an [error handler](crate::error) if the `Result` is an error. /// /// The [default error handler](crate::error::default_error_handler) panics. -/// It can be configured by setting the `GLOBAL_ERROR_HANDLER`. +/// It can be configured via [`set_global_default_error_handler`](crate::error::set_global_default_error_handler). /// /// Alternatively, you can customize the error handler for a specific command /// by calling [`Commands::queue_handled`]. @@ -1224,7 +1224,7 @@ impl<'w, 's> Commands<'w, 's> { /// which will be passed to an [error handler](crate::error) if the `Result` is an error. /// /// The [default error handler](crate::error::default_error_handler) panics. -/// It can be configured by setting the `GLOBAL_ERROR_HANDLER`. +/// It can be configured via [`set_global_default_error_handler`](crate::error::set_global_default_error_handler). /// /// Alternatively, you can customize the error handler for a specific command /// by calling [`EntityCommands::queue_handled`]. diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index f4c2f2f03100d..98a292ec8a44d 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -289,9 +289,6 @@ custom_cursor = ["bevy_winit/custom_cursor"] # Experimental support for nodes that are ignored for UI layouting ghost_nodes = ["bevy_ui/ghost_nodes"] -# Use the configurable global error handler as the default error handler. -configurable_error_handler = ["bevy_ecs/configurable_error_handler"] - # Allows access to the `std` crate. Enabling this feature will prevent compilation # on `no_std` targets, but provides access to certain additional features on # supported platforms. diff --git a/docs/cargo_features.md b/docs/cargo_features.md index 774dafe952889..72b3d6e170b49 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -70,7 +70,6 @@ The default feature set enables most of the expected features of a game engine, |bevy_remote|Enable the Bevy Remote Protocol| |bevy_ui_debug|Provides a debug overlay for bevy UI| |bmp|BMP image format support| -|configurable_error_handler|Use the configurable global error handler as the default error handler.| |critical-section|`critical-section` provides the building blocks for synchronization primitives on all platforms, including `no_std`.| |dds|DDS compressed texture support| |debug_glam_assert|Enable assertions in debug builds to check the validity of parameters passed to glam| diff --git a/examples/ecs/error_handling.rs b/examples/ecs/error_handling.rs index b13a018530fc0..23da8186e96da 100644 --- a/examples/ecs/error_handling.rs +++ b/examples/ecs/error_handling.rs @@ -1,11 +1,8 @@ //! Showcases how fallible systems and observers can make use of Rust's powerful result handling //! syntax. -//! -//! Important note: to set the global error handler, the `configurable_error_handler` feature must be -//! enabled. This feature is disabled by default, as it may introduce runtime overhead, especially for commands. use bevy::ecs::{ - error::{warn, GLOBAL_ERROR_HANDLER}, + error::{set_global_default_error_handler, warn}, world::DeferredWorld, }; use bevy::math::sampling::UniformMeshSampler; @@ -22,9 +19,7 @@ fn main() { // Here we set the global error handler using one of the built-in // error handlers. Bevy provides built-in handlers for `panic`, `error`, `warn`, `info`, // `debug`, `trace` and `ignore`. - GLOBAL_ERROR_HANDLER - .set(warn) - .expect("The error handler can only be set once, globally."); + set_global_default_error_handler(warn); let mut app = App::new(); diff --git a/examples/ecs/fallible_params.rs b/examples/ecs/fallible_params.rs index 99eaedf10d071..27fe25ff986df 100644 --- a/examples/ecs/fallible_params.rs +++ b/examples/ecs/fallible_params.rs @@ -2,7 +2,7 @@ //! from running if their acquiry conditions aren't met. //! //! Fallible system parameters include: -//! - [`Res`], [`ResMut`] - Resource has to exist, and the [`GLOBAL_ERROR_HANDLER`] will be called if it doesn't. +//! - [`Res`], [`ResMut`] - Resource has to exist, and the [`default_error_handler`] will be called if it doesn't. //! - [`Single`] - There must be exactly one matching entity, but the system will be silently skipped otherwise. //! - [`Option>`] - There must be zero or one matching entity. The system will be silently skipped if there are more. //! - [`Populated`] - There must be at least one matching entity, but the system will be silently skipped otherwise. @@ -18,18 +18,17 @@ //! //! [`SystemParamValidationError`]: bevy::ecs::system::SystemParamValidationError //! [`SystemParam::validate_param`]: bevy::ecs::system::SystemParam::validate_param +//! [`default_error_handler`]: bevy::ecs::error::default_error_handler -use bevy::ecs::error::{warn, GLOBAL_ERROR_HANDLER}; +use bevy::ecs::error::{set_global_default_error_handler, warn}; use bevy::prelude::*; use rand::Rng; fn main() { // By default, if a parameter fail to be fetched, - // the `GLOBAL_ERROR_HANDLER` will be used to handle the error, + // the `default_error_handler` will be used to handle the error, // which by default is set to panic. - GLOBAL_ERROR_HANDLER - .set(warn) - .expect("The error handler can only be set once, globally."); + set_global_default_error_handler(warn); println!(); println!("Press 'A' to add enemy ships and 'R' to remove them."); From 3e678e2ee992fc8ff3511d6098f9effbaf26d6a8 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Fri, 11 Apr 2025 10:17:25 +0200 Subject: [PATCH 2/5] review comments --- crates/bevy_ecs/src/error/handler.rs | 40 +++++++++++++++------------- crates/bevy_ecs/src/error/mod.rs | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/crates/bevy_ecs/src/error/handler.rs b/crates/bevy_ecs/src/error/handler.rs index 3d20a34b6683f..2b638b57b122c 100644 --- a/crates/bevy_ecs/src/error/handler.rs +++ b/crates/bevy_ecs/src/error/handler.rs @@ -76,14 +76,20 @@ impl ErrorContext { } mod global_error_handler { - use super::{BevyError, ErrorContext}; + use super::{panic, BevyError, ErrorContext}; use bevy_platform_support::sync::atomic::{ - AtomicPtr, + AtomicBool, AtomicPtr, Ordering::{AcqRel, Acquire, Relaxed}, }; + // The default global error handler, cast to a data pointer as Rust doesn't + // currently have a way to express atomic function pointers. + // Should we add support for a platform on which function pointers and data pointers + // have different sizes, the transmutation back will fail to compile. In that case, + // we can replace the atomic pointer with a regular pointer protected by a `RwLock` + // on only those platforms. // SAFETY: Only accessible from within this module. - static HANDLER_ADDRESS: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut()); + static HANDLER: AtomicPtr<()> = AtomicPtr::new(panic as *mut ()); /// Set the global error handler. /// @@ -116,35 +122,33 @@ mod global_error_handler { /// [before]: https://doc.rust-lang.org/nightly/core/sync/atomic/index.html#memory-model-for-atomic-accesses /// [`default_error_handler`]: super::default_error_handler pub fn set_global_default_error_handler(handler: fn(BevyError, ErrorContext)) { - if HANDLER_ADDRESS - .compare_exchange(core::ptr::null_mut(), handler as *mut (), AcqRel, Acquire) + // Prevent the handler from being set multiple times. + // We use a seperate atomic instead of trying `compare_exchange` on `HANDLER_ADDRESS` + // because Rust doesn't guarantee that function addresses are unique. + static INITIALIZED: AtomicBool = AtomicBool::new(false); + if INITIALIZED + .compare_exchange(false, true, AcqRel, Acquire) .is_err() { panic!("Global error handler set multiple times"); } + HANDLER.store(handler as *mut (), Relaxed); } + /// The default error handler. This defaults to [`panic`], + /// but you can override this behavior via [`set_global_default_error_handler`]. #[inline] - pub(super) fn get() -> Option { + pub fn default_error_handler() -> fn(BevyError, ErrorContext) { // The error handler must have been already set from the perspective of this thread, // otherwise we will panic. It will never be updated after this point. // We therefore only need a relaxed load. - let ptr = HANDLER_ADDRESS.load(Relaxed); - // SAFETY: We only ever store null or a valid handler function. - // `null` is guaranteed to be represent `None`: - // https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html#representation + let ptr = HANDLER.load(Relaxed); + // SAFETY: We only ever store valid handler functions. unsafe { core::mem::transmute(ptr) } } } -pub use global_error_handler::set_global_default_error_handler; - -/// The default error handler. This defaults to [`panic()`], -/// but you can override this behavior via [`set_global_error_handler`]. -#[inline] -pub fn default_error_handler() -> fn(BevyError, ErrorContext) { - global_error_handler::get().unwrap_or(panic) -} +pub use global_error_handler::{default_error_handler, set_global_default_error_handler}; macro_rules! inner { ($call:path, $e:ident, $c:ident) => { diff --git a/crates/bevy_ecs/src/error/mod.rs b/crates/bevy_ecs/src/error/mod.rs index f4ac4fa9b7b2b..7ae674daa5f8d 100644 --- a/crates/bevy_ecs/src/error/mod.rs +++ b/crates/bevy_ecs/src/error/mod.rs @@ -8,7 +8,7 @@ //! [`panic`] error handler function is used, resulting in a panic with the error message attached. //! //! You can change the default behavior by registering a custom error handler: -//! Use [`set_global_default_error_handler`](crate::error::set_global_default_error_handler) +//! Use [`set_global_default_error_handler`] //! to set a custom error handler function for your entire app. //! In practice, this is generally feature-flagged: panicking or loudly logging errors in development, //! and quietly logging or ignoring them in production to avoid crashing the app. From 1ebe00979db18da6547c7fdea77b7d275c7ef65b Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Fri, 11 Apr 2025 10:24:49 +0200 Subject: [PATCH 3/5] typo --- crates/bevy_ecs/src/error/handler.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/bevy_ecs/src/error/handler.rs b/crates/bevy_ecs/src/error/handler.rs index 2b638b57b122c..0f5ee382531b9 100644 --- a/crates/bevy_ecs/src/error/handler.rs +++ b/crates/bevy_ecs/src/error/handler.rs @@ -82,13 +82,13 @@ mod global_error_handler { Ordering::{AcqRel, Acquire, Relaxed}, }; - // The default global error handler, cast to a data pointer as Rust doesn't - // currently have a way to express atomic function pointers. - // Should we add support for a platform on which function pointers and data pointers - // have different sizes, the transmutation back will fail to compile. In that case, - // we can replace the atomic pointer with a regular pointer protected by a `RwLock` - // on only those platforms. - // SAFETY: Only accessible from within this module. + /// The default global error handler, cast to a data pointer as Rust doesn't + /// currently have a way to express atomic function pointers. + /// Should we add support for a platform on which function pointers and data pointers + /// have different sizes, the transmutation back will fail to compile. In that case, + /// we can replace the atomic pointer with a regular pointer protected by a `RwLock` + /// on only those platforms. + /// SAFETY: Only accessible from within this module. static HANDLER: AtomicPtr<()> = AtomicPtr::new(panic as *mut ()); /// Set the global error handler. @@ -107,7 +107,7 @@ mod global_error_handler { /// To use this error handler in your app for custom error handling logic: /// /// ```rust - /// use bevy_ecs::error::{default_error_handler, BevyError, ErrorContext, panic}; + /// use bevy_ecs::error::{default_error_handler, BevyError, ErrorContext}; /// /// fn handle_errors(error: BevyError, ctx: ErrorContext) { /// let error_handler = default_error_handler(); @@ -123,7 +123,7 @@ mod global_error_handler { /// [`default_error_handler`]: super::default_error_handler pub fn set_global_default_error_handler(handler: fn(BevyError, ErrorContext)) { // Prevent the handler from being set multiple times. - // We use a seperate atomic instead of trying `compare_exchange` on `HANDLER_ADDRESS` + // We use a separate atomic instead of trying `compare_exchange` on `HANDLER_ADDRESS` // because Rust doesn't guarantee that function addresses are unique. static INITIALIZED: AtomicBool = AtomicBool::new(false); if INITIALIZED @@ -137,6 +137,8 @@ mod global_error_handler { /// The default error handler. This defaults to [`panic`], /// but you can override this behavior via [`set_global_default_error_handler`]. + /// + /// [`panic`]: super::panic #[inline] pub fn default_error_handler() -> fn(BevyError, ErrorContext) { // The error handler must have been already set from the perspective of this thread, From d5304dc7575350e2ef772c8cc90900bbfe6b15b5 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Fri, 11 Apr 2025 15:27:14 +0200 Subject: [PATCH 4/5] update comment --- crates/bevy_ecs/src/error/handler.rs | 2 +- crates/bevy_ecs/src/error/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/error/handler.rs b/crates/bevy_ecs/src/error/handler.rs index 0f5ee382531b9..4ebf14a0a6767 100644 --- a/crates/bevy_ecs/src/error/handler.rs +++ b/crates/bevy_ecs/src/error/handler.rs @@ -86,7 +86,7 @@ mod global_error_handler { /// currently have a way to express atomic function pointers. /// Should we add support for a platform on which function pointers and data pointers /// have different sizes, the transmutation back will fail to compile. In that case, - /// we can replace the atomic pointer with a regular pointer protected by a `RwLock` + /// we can replace the atomic pointer with a regular pointer protected by a `OnceLock` /// on only those platforms. /// SAFETY: Only accessible from within this module. static HANDLER: AtomicPtr<()> = AtomicPtr::new(panic as *mut ()); diff --git a/crates/bevy_ecs/src/error/mod.rs b/crates/bevy_ecs/src/error/mod.rs index 7ae674daa5f8d..bb3016d5d513a 100644 --- a/crates/bevy_ecs/src/error/mod.rs +++ b/crates/bevy_ecs/src/error/mod.rs @@ -35,7 +35,7 @@ //! context surrounding the error – such as the system's [`name`] – in your error messages. //! //! ```rust, ignore -//! use bevy_ecs::error::{set_global_error_handler, BevyError, ErrorContext}; +//! use bevy_ecs::error::{set_global_default_error_handler, BevyError, ErrorContext}; //! use log::trace; //! //! fn my_error_handler(error: BevyError, ctx: ErrorContext) { @@ -47,7 +47,7 @@ //! } //! //! fn main() { -//! set_global_error_handler(my_error_handler); +//! set_global_default_error_handler(my_error_handler); //! //! // Initialize your Bevy App here //! } From fb625e520f69fd06167dd79d9f6c1eaf8363d461 Mon Sep 17 00:00:00 2001 From: SpecificProtagonist Date: Sat, 12 Apr 2025 05:06:33 +0200 Subject: [PATCH 5/5] =?UTF-8?q?bevy=5Fplatform=5Fsupport=20=E2=86=92=20bev?= =?UTF-8?q?y=5Fplatform?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/bevy_ecs/src/error/handler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/error/handler.rs b/crates/bevy_ecs/src/error/handler.rs index 4ebf14a0a6767..a684ec0ebcb49 100644 --- a/crates/bevy_ecs/src/error/handler.rs +++ b/crates/bevy_ecs/src/error/handler.rs @@ -77,7 +77,7 @@ impl ErrorContext { mod global_error_handler { use super::{panic, BevyError, ErrorContext}; - use bevy_platform_support::sync::atomic::{ + use bevy_platform::sync::atomic::{ AtomicBool, AtomicPtr, Ordering::{AcqRel, Acquire, Relaxed}, };