cfx_rpc_utils/error/
jsonrpc_error_helpers.rs

1use crate::error::error_codes as codes;
2use alloy_primitives::hex;
3use alloy_rpc_types::error::EthRpcErrorCode;
4use cfx_types::H256;
5use jsonrpc_core::{Error, ErrorCode, Value};
6use jsonrpsee::types::ErrorObjectOwned;
7use std::fmt;
8
9/// Constructs a JSON-RPC error, consisting of `code`, `message` and optional
10/// `data`.
11pub fn rpc_err(
12    code: i32, msg: impl Into<String>, data: Option<&[u8]>,
13) -> Error {
14    Error {
15        code: ErrorCode::from(code as i64),
16        message: msg.into(),
17        data: data.map(|v| serde_json::Value::String(hex::encode_prefixed(v))),
18    }
19}
20
21pub fn build_rpc_server_error(code: i64, message: String) -> Error {
22    Error {
23        code: ErrorCode::ServerError(code),
24        message,
25        data: None,
26    }
27}
28
29pub fn unimplemented(details: Option<String>) -> Error {
30    Error {
31        code: ErrorCode::ServerError(codes::UNSUPPORTED),
32        message: "This API is not implemented yet".into(),
33        data: details.map(Value::String),
34    }
35}
36
37// code is -32000
38pub fn invalid_input_rpc_err(msg: impl Into<String>) -> Error {
39    rpc_err(EthRpcErrorCode::InvalidInput.code(), msg, None)
40}
41
42/// Constructs an invalid params JSON-RPC error.
43pub fn invalid_params_rpc_err(msg: impl Into<String>) -> Error {
44    rpc_err(ErrorCode::InvalidParams.code() as i32, msg, None)
45}
46
47pub fn invalid_params<T: fmt::Debug>(param: &str, details: T) -> Error {
48    Error {
49        code: ErrorCode::InvalidParams,
50        message: format!("Invalid parameters: {}", param),
51        data: Some(Value::String(format!("{:?}", details))),
52    }
53}
54
55pub fn invalid_params_check<T, E: std::fmt::Display>(
56    param: &str, r: std::result::Result<T, E>,
57) -> Result<T, Error> {
58    match r {
59        Ok(t) => Ok(t),
60        Err(e) => Err(invalid_params(param.into(), format!("{}", e)).into()),
61    }
62}
63
64pub fn invalid_params_msg(param: &str) -> Error {
65    invalid_params_rpc_err(format!("Invalid parameters: {}", param))
66}
67
68pub fn invalid_params_detail<T: fmt::Debug>(param: &str, details: T) -> Error {
69    Error {
70        code: ErrorCode::InvalidParams,
71        message: format!("Invalid parameters: {} {:?}", param, details),
72        data: Some(Value::String(format!("{:?}", details))),
73    }
74}
75
76pub fn unknown_block() -> Error {
77    Error {
78        code: ErrorCode::InvalidParams,
79        message: "Unknown block number".into(),
80        data: None,
81    }
82}
83
84/// Constructs an internal JSON-RPC error.
85pub fn internal_rpc_err(msg: impl Into<String>) -> Error {
86    rpc_err(ErrorCode::InternalError.code() as i32, msg, None)
87}
88
89/// Constructs an internal JSON-RPC error with data
90pub fn internal_rpc_err_with_data(
91    msg: impl Into<String>, data: &[u8],
92) -> Error {
93    rpc_err(ErrorCode::InternalError.code() as i32, msg, Some(data))
94}
95
96pub fn internal_error_msg(param: &str) -> Error {
97    Error {
98        code: ErrorCode::InternalError,
99        message: format!("Internal error: {}", param),
100        data: None,
101    }
102}
103
104pub fn internal_error<T: fmt::Debug>(details: T) -> Error {
105    Error {
106        code: ErrorCode::InternalError,
107        message: "Internal error".into(),
108        data: Some(Value::String(format!("{:?}", details))),
109    }
110}
111
112pub fn call_execution_error(message: String, data: String) -> Error {
113    Error {
114        code: ErrorCode::ServerError(codes::CALL_EXECUTION_ERROR),
115        message,
116        data: Some(Value::String(data)),
117    }
118}
119
120pub fn geth_call_execution_error(message: String, data: String) -> Error {
121    Error {
122        code: ErrorCode::ServerError(
123            EthRpcErrorCode::ExecutionError.code() as i64
124        ),
125        message,
126        data: Some(Value::String(data)),
127    }
128}
129
130pub fn request_rejected_too_many_request_error(
131    details: Option<String>,
132) -> Error {
133    Error {
134        code: ErrorCode::ServerError(codes::REQUEST_REJECTED_TOO_MANY_REQUESTS),
135        message: "Request rejected.".into(),
136        data: details.map(Value::String),
137    }
138}
139
140pub fn request_rejected_in_catch_up_mode(details: Option<String>) -> Error {
141    Error {
142        code: ErrorCode::ServerError(codes::REQUEST_REJECTED_IN_CATCH_UP),
143        message: "Request rejected due to still in the catch up mode.".into(),
144        data: details.map(Value::String),
145    }
146}
147
148pub fn pivot_assumption_failed(expected: H256, got: H256) -> Error {
149    Error {
150        code: ErrorCode::ServerError(codes::CONFLUX_PIVOT_CHAIN_UNSTABLE),
151        message: "pivot chain assumption failed".into(),
152        data: Some(Value::String(format!(
153            "pivot assumption: {:?}, actual pivot hash: {:?}",
154            expected, got
155        ))),
156    }
157}
158
159pub fn error_object_owned_to_jsonrpc_error(e: ErrorObjectOwned) -> Error {
160    Error {
161        code: ErrorCode::from(e.code() as i64),
162        message: e.message().into(),
163        data: e.data().map(|v| Value::String(v.to_string())),
164    }
165}