use crate::errors::ExecutionError;
use jsonrpc_core::Error as JsonrpcError;
pub fn get_encoded_error(err: &JsonrpcError) -> Option<ExecutionError> {
if err.message == "VM Exception while processing transaction: invalid opcode" {
return Some(ExecutionError::InvalidOpcode);
}
if let Some(reason) = err
.message
.strip_prefix(
"Error: VM Exception while processing transaction: reverted with reason string '",
)
.and_then(|rest| rest.strip_suffix('\''))
{
return Some(ExecutionError::Revert(Some(reason.to_owned())));
}
for needle in ["VM Exception", "Transaction reverted"] {
if err.message.contains(needle) {
return Some(ExecutionError::Revert(None));
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test::prelude::*;
use jsonrpc_core::ErrorCode;
#[test]
fn execution_error_from_revert_with_message() {
let jsonrpc_err = JsonrpcError {
code: ErrorCode::InternalError,
message: "Error: VM Exception while processing transaction: \
reverted with reason string 'GS020'"
.to_owned(),
data: Some(json!({
"data": "0x08c379a0\
0000000000000000000000000000000000000000000000000000000000000020\
0000000000000000000000000000000000000000000000000000000000000005\
4753303230000000000000000000000000000000000000000000000000000000",
"message": "Error: VM Exception while processing transaction: \
reverted with reason string 'GS020'"
})),
};
let err = get_encoded_error(&jsonrpc_err);
assert!(
matches!(
&err,
Some(ExecutionError::Revert(Some(reason))) if reason == "GS020"
),
"bad error conversion {err:?}",
);
}
}