Skip to content

Commit e779397

Browse files
committed
feat: add Severity to BevyError
1 parent 2e45788 commit e779397

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

crates/bevy_ecs/src/error/bevy_error.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
98105
struct 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!
105170
impl<E> From<E> for BevyError
106171
where
@@ -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

Comments
 (0)