-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Add new and severity based constructors to BevyError
#23684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+133
−4
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
bcae0a9
Add `BevyError::new`
loreball fa1ef76
Add helpers to BevyError
loreball 579cd27
Don't attempt to set RUST_BACKTRACE in filtered_backtrace_test
loreball 65e1337
Fix `BevyError::new` documentation
loreball 9c50aca
Change bounds for BevyError::new to allow the direct use of strings
loreball c923d8e
Add severity based constructors to `BevyError`
loreball 09a0596
Fix some typos
benfrankel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,112 @@ pub struct BevyError { | |
| } | ||
|
|
||
| impl BevyError { | ||
| /// Constructs a new [`BevyError`] with the given [`Severity`]. | ||
| /// | ||
| /// The stored error will be stored as a `Box<dyn Error + Send + Sync>`. | ||
| /// | ||
| /// The easiest way to use this is to simply pass in a quoted bit of text. | ||
alice-i-cecile marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// This works because any type that can be converted into a `Box<dyn Error + Send + Sync>` can be used, | ||
| /// and [`str`] is one such type. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// # use bevy_ecs::error::{BevyError, Severity}; | ||
| /// | ||
| /// fn some_function(val: i64) -> Result<(), BevyError> { | ||
| /// if val < 0 { | ||
| /// let error = | ||
| /// BevyError::new(Severity::Panic, format!("Value can't be negative {val}")); | ||
| /// return Err(error); | ||
| /// } | ||
| /// | ||
| /// // ... | ||
| /// Ok(()) | ||
| /// } | ||
| /// ``` | ||
| pub fn new<E>(severity: Severity, error: E) -> Self | ||
| where | ||
| Box<dyn Error + Sync + Send>: From<E>, | ||
| { | ||
| Self::from(error).with_severity(severity) | ||
alice-i-cecile marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Ignore`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Ignore, error)](BevyError::new)</code> | ||
alice-i-cecile marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pub fn ignore<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Ignore, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Trace`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Trace, error)](BevyError::new)</code> | ||
| pub fn trace<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Trace, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Debug`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Debug, error)](BevyError::new)</code> | ||
| pub fn debug<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Debug, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Info`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Info, error)](BevyError::new)</code> | ||
| pub fn info<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Info, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Warning`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Warning, error)](BevyError::new)</code> | ||
| pub fn warning<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Warning, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Error`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Error, error)](BevyError::new)</code> | ||
| pub fn error<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Error, error) | ||
| } | ||
|
|
||
| /// Create a new [`BevyError`] with the [`Severity::Panic`] severity | ||
| /// | ||
| /// This is a shorthand for <code>[BevyError::new(Severity::Panic, error)](BevyError::new)</code> | ||
| pub fn panic<E>(error: E) -> Self | ||
| where | ||
| Box<dyn Error + Send + Sync>: From<E>, | ||
| { | ||
| Self::new(Severity::Panic, error) | ||
| } | ||
|
|
||
| /// Checks if we're holding the internal error. | ||
|
||
| pub fn is<E: Error + 'static>(&self) -> bool { | ||
| self.inner.error.is::<E>() | ||
| } | ||
|
|
||
| /// Attempts to downcast the internal error to the given type. | ||
| pub fn downcast_ref<E: Error + 'static>(&self) -> Option<&E> { | ||
| self.inner.error.downcast_ref::<E>() | ||
|
|
@@ -65,6 +171,7 @@ impl BevyError { | |
| let f = _f; | ||
| let backtrace = &self.inner.backtrace; | ||
| if let std::backtrace::BacktraceStatus::Captured = backtrace.status() { | ||
| // TODO: Cache | ||
| let full_backtrace = std::env::var("BEVY_BACKTRACE").is_ok_and(|val| val == "full"); | ||
|
|
||
| let backtrace_str = alloc::string::ToString::to_string(backtrace); | ||
|
|
@@ -268,6 +375,7 @@ pub fn bevy_error_panic_hook( | |
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use crate::error::BevyError; | ||
|
|
||
| #[test] | ||
| #[cfg(not(miri))] // miri backtraces are weird | ||
|
|
@@ -278,11 +386,11 @@ mod tests { | |
| Ok(()) | ||
| } | ||
|
|
||
| // SAFETY: this is not safe ... this test could run in parallel with another test | ||
| // that writes the environment variable. We either accept that so we can write this test, | ||
| // or we don't. | ||
| let capture_backtrace = std::env::var_os("RUST_BACKTRACE"); | ||
|
|
||
| unsafe { std::env::set_var("RUST_BACKTRACE", "1") }; | ||
| if capture_backtrace.is_none() || capture_backtrace.clone().is_some_and(|s| s == "0") { | ||
| panic!("This test only works if rust backtraces are enabled. Value set was {capture_backtrace:?}. Please set RUST_BACKTRACE to any value other than 0 and run again.") | ||
| } | ||
|
|
||
| let error = i_fail().err().unwrap(); | ||
| let debug_message = alloc::format!("{error:?}"); | ||
|
|
@@ -349,4 +457,22 @@ mod tests { | |
| assert_eq!(super::FILTER_MESSAGE, lines.next().unwrap()); | ||
| assert!(lines.next().is_none()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn downcasting() { | ||
| #[derive(Debug, PartialEq)] | ||
| struct Fun(i32); | ||
|
|
||
| impl core::fmt::Display for Fun { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| core::fmt::Debug::fmt(&self, f) | ||
| } | ||
| } | ||
| impl core::error::Error for Fun {} | ||
|
|
||
| let new_error = BevyError::new(crate::error::Severity::Debug, Fun(1)); | ||
|
|
||
| assert!(new_error.is::<Fun>()); | ||
| assert_eq!(new_error.downcast_ref::<Fun>(), Some(&Fun(1))); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.