Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contracts/staking/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ pub fn _bond_all_tokens(
}) {
Ok(_) => {}
// if it is below the minimum, we do a no-op (do not revert other state from withdrawal)
Err(StdError::Overflow(_)) => return Ok(Response::default()),
Err(StdError::Overflow { .. }) => return Ok(Response::default()),
Err(e) => return Err(e.into()),
}

Expand Down Expand Up @@ -739,7 +739,7 @@ mod tests {
let res = execute(deps.as_mut(), mock_env(), info, unbond_msg);
match res.unwrap_err() {
StakingError::Std {
original: StdError::Overflow(_),
original: StdError::Overflow { .. },
} => {}
err => panic!("Unexpected error: {:?}", err),
}
Expand Down
137 changes: 102 additions & 35 deletions packages/std/src/errors/std_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,18 @@ pub enum StdError {
#[cfg(feature = "backtraces")]
backtrace: Backtrace,
},
#[error(transparent)]
Overflow(#[from] OverflowError),
#[error(transparent)]
DivideByZero(#[from] DivideByZeroError),
#[error("Overflow: {source}")]
Overflow {
source: OverflowError,
#[cfg(feature = "backtraces")]
backtrace: Backtrace,
},
#[error("Divide by zero: {source}")]
DivideByZero {
source: DivideByZeroError,
#[cfg(feature = "backtraces")]
backtrace: Backtrace,
},
}

impl StdError {
Expand Down Expand Up @@ -165,6 +173,22 @@ impl StdError {
backtrace: Backtrace::capture(),
}
}

pub fn overflow(source: OverflowError) -> Self {
StdError::Overflow {
source,
#[cfg(feature = "backtraces")]
backtrace: Backtrace::capture(),
}
}

pub fn divide_by_zero(source: DivideByZeroError) -> Self {
StdError::DivideByZero {
source,
#[cfg(feature = "backtraces")]
backtrace: Backtrace::capture(),
}
}
}

impl PartialEq<StdError> for StdError {
Expand Down Expand Up @@ -320,16 +344,34 @@ impl PartialEq<StdError> for StdError {
false
}
}
StdError::Overflow(err) => {
if let StdError::Overflow(rhs_err) = rhs {
err == rhs_err
StdError::Overflow {
source,
#[cfg(feature = "backtraces")]
backtrace: _,
} => {
if let StdError::Overflow {
source: rhs_source,
#[cfg(feature = "backtraces")]
backtrace: _,
} = rhs
{
source == rhs_source
} else {
false
}
}
StdError::DivideByZero(err) => {
if let StdError::DivideByZero(rhs_err) = rhs {
err == rhs_err
StdError::DivideByZero {
source,
#[cfg(feature = "backtraces")]
backtrace: _,
} => {
if let StdError::DivideByZero {
source: rhs_source,
#[cfg(feature = "backtraces")]
backtrace: _,
} = rhs
{
source == rhs_source
} else {
false
}
Expand Down Expand Up @@ -362,6 +404,18 @@ impl From<RecoverPubkeyError> for StdError {
}
}

impl From<OverflowError> for StdError {
fn from(source: OverflowError) -> Self {
Self::overflow(source)
}
}

impl From<DivideByZeroError> for StdError {
fn from(source: DivideByZeroError) -> Self {
Self::divide_by_zero(source)
}
}

/// The return type for init, execute and query. Since the error type cannot be serialized to JSON,
/// this is only available within the contract and its unit tests.
///
Expand Down Expand Up @@ -389,8 +443,6 @@ pub struct OverflowError {
pub operation: OverflowOperation,
pub operand1: String,
pub operand2: String,
#[cfg(feature = "backtraces")]
backtrace: Backtrace,
}

impl OverflowError {
Expand All @@ -399,8 +451,6 @@ impl OverflowError {
operation,
operand1: operand1.to_string(),
operand2: operand2.to_string(),
#[cfg(feature = "backtraces")]
backtrace: Backtrace::capture(),
}
}
}
Expand All @@ -409,16 +459,12 @@ impl OverflowError {
#[error("Cannot devide {operand} by zero")]
pub struct DivideByZeroError {
pub operand: String,
#[cfg(feature = "backtraces")]
backtrace: Backtrace,
}

impl DivideByZeroError {
pub fn new<U: ToString>(operand: U) -> Self {
Self {
operand: operand.to_string(),
#[cfg(feature = "backtraces")]
backtrace: Backtrace::capture(),
}
}
}
Expand Down Expand Up @@ -552,14 +598,19 @@ mod tests {

#[test]
fn underflow_works_for_u128() {
let error = StdError::from(OverflowError::new(OverflowOperation::Sub, 123u128, 456u128));
let error =
StdError::overflow(OverflowError::new(OverflowOperation::Sub, 123u128, 456u128));
match error {
StdError::Overflow(OverflowError {
operation: OverflowOperation::Sub,
operand1,
operand2,
StdError::Overflow {
source:
OverflowError {
operation,
operand1,
operand2,
},
..
}) => {
} => {
assert_eq!(operation, OverflowOperation::Sub);
assert_eq!(operand1, "123");
assert_eq!(operand2, "456");
}
Expand All @@ -568,37 +619,53 @@ mod tests {
}

#[test]
fn underflow_works_for_i64() {
let error = StdError::from(OverflowError::new(OverflowOperation::Sub, 777i64, 1234i64));
fn overflow_works_for_i64() {
let error = StdError::overflow(OverflowError::new(OverflowOperation::Sub, 777i64, 1234i64));
match error {
StdError::Overflow(OverflowError {
operation: OverflowOperation::Sub,
operand1,
operand2,
StdError::Overflow {
source:
OverflowError {
operation,
operand1,
operand2,
},
..
}) => {
} => {
assert_eq!(operation, OverflowOperation::Sub);
assert_eq!(operand1, "777");
assert_eq!(operand2, "1234");
}
_ => panic!("expect different error"),
}
}

#[test]
fn divide_by_zero_works() {
let error = StdError::divide_by_zero(DivideByZeroError::new(123u128));
match error {
StdError::DivideByZero {
source: DivideByZeroError { operand },
..
} => assert_eq!(operand, "123"),
_ => panic!("expect different error"),
}
}

#[test]
fn implements_debug() {
let error: StdError = StdError::from(OverflowError::new(OverflowOperation::Sub, 3, 5));
let embedded = format!("Debug message: {:?}", error);
let embedded = format!("Debug: {:?}", error);
assert_eq!(
embedded,
r#"Debug message: Overflow(OverflowError { operation: Sub, operand1: "3", operand2: "5" })"#
r#"Debug: Overflow { source: OverflowError { operation: Sub, operand1: "3", operand2: "5" } }"#
);
}

#[test]
fn implements_display() {
let error: StdError = StdError::from(OverflowError::new(OverflowOperation::Sub, 3, 5));
let embedded = format!("Display message: {}", error);
assert_eq!(embedded, "Display message: Cannot Sub with 3 and 5");
let embedded = format!("Display: {}", error);
assert_eq!(embedded, "Display: Overflow: Cannot Sub with 3 and 5");
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion packages/storage/src/singleton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ mod tests {
)))
});
match output.unwrap_err() {
StdError::Overflow(_) => {}
StdError::Overflow { .. } => {}
err => panic!("Unexpected error: {:?}", err),
}
assert_eq!(writer.load().unwrap(), cfg);
Expand Down