@@ -7,6 +7,13 @@ use core::{
77/// The built in "universal" Bevy error type. This has a blanket [`From`] impl for any type that implements Rust's [`Error`],
88/// meaning it can be used as a "catch all" error.
99///
10+ /// # Severity
11+ ///
12+ /// Each [`BevyError`] carries a [`Severity`] value that indicates how serious the error is. Severity is advisory
13+ /// metadata used by error handlers to decide how to react (for example: ignore, log, or panic).
14+ ///
15+ /// By default, errors have [`Severity::Critical`], which preserves Bevy’s known panic-on-error behavior unless explicitly overridden.
16+ ///
1017/// # Backtraces
1118///
1219/// When used with the `backtrace` Cargo feature, it will capture a backtrace when the error is constructed (generally in the [`From`] impl]).
@@ -97,10 +104,68 @@ impl BevyError {
97104/// of the current impl is nice.
98105struct InnerBevyError {
99106 error : Box < dyn Error + Send + Sync + ' static > ,
107+ severity : Severity ,
100108 #[ cfg( feature = "backtrace" ) ]
101109 backtrace : std:: backtrace:: Backtrace ,
102110}
103111
112+ /// Indicates how severe a [`BevyError`] is.
113+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
114+ pub enum Severity {
115+ /// The error can be safely ignored.
116+ Ignore ,
117+ /// Something unexpected but recoverable happened.
118+ Warning ,
119+ /// A real error occurred, but the program may continue.
120+ Error ,
121+ /// A fatal error; the default handler may panic.
122+ Critical ,
123+ }
124+
125+ impl BevyError {
126+ /// Returns the severity of this error.
127+ pub fn severity ( & self ) -> Severity {
128+ self . inner . severity
129+ }
130+
131+ /// Returns this error with its severity overridden.
132+ ///
133+ /// Note that this doesn't change the underlying error value;
134+ /// only the [`Severity`] metadata used by the error handler.
135+ pub fn with_severity ( mut self , severity : Severity ) -> Self {
136+ self . inner . severity = severity;
137+ self
138+ }
139+ }
140+
141+ /// Extension methods for annotating errors with a [`Severity`].
142+ pub trait ResultSeverityExt < T > {
143+ /// Overrides the severity of the error if this result is `Err`.
144+ /// This does not change control flow; it only annotates the error.
145+ ///
146+ /// # Example
147+ /// ```
148+ /// # use bevy_ecs::error::{BevyError, ResultSeverityExt, Severity};
149+ /// fn fallible() -> Result<(), BevyError> {
150+ /// // This failure is expected in some contexts, so we downgrade its severity.
151+ /// let _parsed: usize = "I am not a number"
152+ /// .parse()
153+ /// .with_severity(Severity::Warning)?;
154+ /// Ok(())
155+ /// }
156+ /// ```
157+ fn with_severity ( self , severity : Severity ) -> Result < T , BevyError > ;
158+ }
159+
160+ impl < T , E > ResultSeverityExt < T > for Result < T , E >
161+ where
162+ E : Into < BevyError > ,
163+ {
164+ fn with_severity ( self , severity : Severity ) -> Result < T , BevyError > {
165+ self . map_err ( |e| e. into ( ) . with_severity ( severity) )
166+ }
167+ }
168+
104169// NOTE: writing the impl this way gives us From<&str> ... nice!
105170impl < E > From < E > for BevyError
106171where
@@ -111,6 +176,7 @@ where
111176 BevyError {
112177 inner : Box :: new ( InnerBevyError {
113178 error : error. into ( ) ,
179+ severity : Severity :: Critical ,
114180 #[ cfg( feature = "backtrace" ) ]
115181 backtrace : std:: backtrace:: Backtrace :: capture ( ) ,
116182 } ) ,
0 commit comments