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 = 11;
13
14#[derive(Clone, Debug, Error, Serialize)]
15pub enum EthErrors {
16 #[error("{message}")]
17 ExecutionReverted {
18 message: String,
19 data: Option<String>,
20 },
21}
22
23impl EthErrors {
24 pub fn execution_reverted(exit_code: ExitCode, reason: &str, error: &str, data: &[u8]) -> Self {
26 let revert_reason = if reason.is_empty() {
27 String::new()
28 } else {
29 format!(", revert reason=[{reason}]")
30 };
31
32 Self::ExecutionReverted {
33 message: format!(
34 "message execution failed (exit=[{exit_code}]{revert_reason}, vm error=[{error}])"
35 ),
36 data: (!data.is_empty()).then(|| format!("0x{}", hex::encode(data))),
37 }
38 }
39}
40
41impl RpcErrorData for EthErrors {
42 fn error_code(&self) -> Option<i32> {
43 match self {
44 EthErrors::ExecutionReverted { .. } => Some(EXECUTION_REVERTED_CODE),
45 }
46 }
47
48 fn error_message(&self) -> Option<String> {
49 match self {
50 EthErrors::ExecutionReverted { message, .. } => Some(message.clone()),
51 }
52 }
53
54 fn error_data(&self) -> Option<serde_json::Value> {
55 match self {
56 EthErrors::ExecutionReverted { data, .. } => {
57 data.clone().map(serde_json::Value::String)
58 }
59 }
60 }
61}