Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 5565d30

Browse files
ggwpezAnk4n
authored andcommitted
Add defensive_assert! macro (#13423)
* Add defensive_assert macro Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Apply review suggestions Co-authored-by: Bastian Köcher <[email protected]> Signed-off-by: Oliver Tale-Yazdi <[email protected]> --------- Signed-off-by: Oliver Tale-Yazdi <[email protected]>
1 parent a7ae562 commit 5565d30

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

frame/support/src/traits/misc.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ macro_rules! defensive {
4949
);
5050
debug_assert!(false, "{}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR);
5151
};
52-
($error:tt) => {
52+
($error:expr $(,)?) => {
5353
frame_support::log::error!(
5454
target: "runtime",
5555
"{}: {:?}",
@@ -58,7 +58,7 @@ macro_rules! defensive {
5858
);
5959
debug_assert!(false, "{}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error);
6060
};
61-
($error:tt, $proof:tt) => {
61+
($error:expr, $proof:expr $(,)?) => {
6262
frame_support::log::error!(
6363
target: "runtime",
6464
"{}: {:?}: {:?}",
@@ -70,6 +70,25 @@ macro_rules! defensive {
7070
}
7171
}
7272

73+
/// Trigger a defensive failure if a condition is not met.
74+
///
75+
/// Similar to [`assert!`] but will print an error without `debug_assertions` instead of silently
76+
/// ignoring it. Only accepts one instead of variable formatting arguments.
77+
///
78+
/// # Example
79+
///
80+
/// ```should_panic
81+
/// frame_support::defensive_assert!(1 == 0, "Must fail")
82+
/// ```
83+
#[macro_export]
84+
macro_rules! defensive_assert {
85+
($cond:expr $(, $proof:expr )? $(,)?) => {
86+
if !($cond) {
87+
$crate::defensive!(::core::stringify!($cond) $(, $proof )?);
88+
}
89+
};
90+
}
91+
7392
/// Prelude module for all defensive traits to be imported at once.
7493
pub mod defensive_prelude {
7594
pub use super::{Defensive, DefensiveOption, DefensiveResult};
@@ -1141,6 +1160,27 @@ mod test {
11411160
use sp_core::bounded::{BoundedSlice, BoundedVec};
11421161
use sp_std::marker::PhantomData;
11431162

1163+
#[test]
1164+
fn defensive_assert_works() {
1165+
defensive_assert!(true);
1166+
defensive_assert!(true,);
1167+
defensive_assert!(true, "must work");
1168+
defensive_assert!(true, "must work",);
1169+
}
1170+
1171+
#[test]
1172+
#[cfg(debug_assertions)]
1173+
#[should_panic(expected = "Defensive failure has been triggered!: \"1 == 0\": \"Must fail\"")]
1174+
fn defensive_assert_panics() {
1175+
defensive_assert!(1 == 0, "Must fail");
1176+
}
1177+
1178+
#[test]
1179+
#[cfg(not(debug_assertions))]
1180+
fn defensive_assert_does_not_panic() {
1181+
defensive_assert!(1 == 0, "Must fail");
1182+
}
1183+
11441184
#[test]
11451185
#[cfg(not(debug_assertions))]
11461186
fn defensive_saturating_accrue_works() {

0 commit comments

Comments
 (0)