forest/rpc/methods/eth/
errors.rs1use crate::rpc::error::RpcErrorData;
5use crate::shim::error::ExitCode;
6use serde::Serialize;
7use std::fmt::Debug;
8use thiserror::Error;
9
10pub const EXECUTION_REVERTED_CODE: i32 = 3;
13
14#[derive(Clone, Debug, Error, Serialize)]
15pub enum EthErrors {
16 #[error("{message}")]
17 ExecutionReverted { message: String, data: String },
18}
19
20impl EthErrors {
21 pub fn execution_reverted(exit_code: ExitCode, reason: &str, error: &str, data: &[u8]) -> Self {
23 let revert_reason = if reason.is_empty() {
24 String::new()
25 } else {
26 format!(", revert reason=[{reason}]")
27 };
28
29 Self::ExecutionReverted {
30 message: format!(
31 "message execution failed (exit=[{exit_code}]{revert_reason}, vm error=[{error}])"
32 ),
33 data: format!("0x{}", hex::encode(data)),
34 }
35 }
36}
37
38impl RpcErrorData for EthErrors {
39 fn error_code(&self) -> Option<i32> {
40 match self {
41 EthErrors::ExecutionReverted { .. } => Some(EXECUTION_REVERTED_CODE),
42 }
43 }
44
45 fn error_message(&self) -> Option<String> {
46 match self {
47 EthErrors::ExecutionReverted { message, .. } => Some(message.clone()),
48 }
49 }
50
51 fn error_data(&self) -> Option<serde_json::Value> {
52 match self {
53 EthErrors::ExecutionReverted { data, .. } => {
54 Some(serde_json::Value::String(data.clone()))
55 }
56 }
57 }
58}