1use crate::light_protocol::Error as LightProtocolError;
5use cfx_rpc_eth_types::Error as EthRpcError;
6pub use cfx_rpc_utils::error::{
7 error_codes::EXCEPTION_ERROR,
8 jsonrpc_error_helpers::error_object_owned_to_jsonrpc_error,
9};
10use cfx_statedb::Error as StateDbError;
11use cfx_storage::Error as StorageError;
12use cfxcore_errors::ProviderBlockError;
13use jsonrpc_core::{futures::future, Error as JsonRpcError, ErrorCode};
14use jsonrpsee::types::ErrorObjectOwned;
15use primitives::{account::AccountError, filter::FilterError};
16use rlp::DecoderError;
17use serde_json::Value;
18use std::{
19 fmt::{Debug, Display},
20 pin::Pin,
21};
22use thiserror::Error;
23
24#[derive(Debug, Error)]
25pub enum Error {
26 #[error(transparent)]
27 FilterError(#[from] FilterError),
28 #[error(transparent)]
29 Storage(#[from] StorageError),
30 #[error(transparent)]
31 StateDb(#[from] StateDbError),
32 #[error(transparent)]
33 Decoder(#[from] DecoderError),
34 #[error(transparent)]
35 LightProtocol(#[from] LightProtocolError),
36 #[error(
37 "JsonRpcError directly constructed to return to Rpc peer. Error: {0}"
38 )]
39 JsonRpcError(#[from] JsonRpcError),
40 #[error(
41 "JsonRpseeError directly constructed to return to Rpc peer. Error: {0}"
42 )]
43 JsonRpseeError(#[from] ErrorObjectOwned),
44 #[error("Jsonrpc error InvalidParam {0}: {1}.")]
45 InvalidParam(String, String),
46 #[error("Custom error detail: {0}")]
47 Custom(String),
48 #[error("Msg error detail: {0}")]
49 Msg(String),
50}
51
52pub type BoxFuture<T> = Pin<Box<dyn future::Future<Output = Result<T>> + Send>>;
53
54pub type Result<T> = std::result::Result<T, Error>;
55
56impl From<Error> for JsonRpcError {
57 fn from(e: Error) -> JsonRpcError {
58 match e {
59 Error::JsonRpcError(j) => j,
60 Error::JsonRpseeError(e) => error_object_owned_to_jsonrpc_error(e),
61 Error::InvalidParam(param, details) => {
62 JsonRpcError {
63 code: ErrorCode::InvalidParams,
64 message: format!("Invalid parameters: {}", param),
65 data: Some(Value::String(format!("{:?}", details))),
66 }
67 }
68 Error::Msg(_)
69 | Error::Decoder(_)
70
71 | Error::FilterError(_)
73
74 | Error::LightProtocol(_)
76 | Error::StateDb(_)
77 | Error::Storage(_)
78 | Error::Custom(_) => JsonRpcError {
79 code: ErrorCode::ServerError(EXCEPTION_ERROR),
80 message: format!("Error processing request: {}", e),
81 data: None,
82 },
83 }
84 }
85}
86
87impl From<Error> for ErrorObjectOwned {
88 fn from(e: Error) -> ErrorObjectOwned {
89 let err: JsonRpcError = e.into();
90 ErrorObjectOwned::owned(err.code.code() as i32, err.message, err.data)
91 }
92}
93
94impl From<&str> for Error {
95 fn from(s: &str) -> Error { Error::Msg(s.into()) }
96}
97
98impl From<String> for Error {
99 fn from(s: String) -> Error { Error::Msg(s) }
100}
101
102impl From<ProviderBlockError> for Error {
103 fn from(e: ProviderBlockError) -> Error { Error::from(e.to_string()) }
104}
105
106impl From<EthRpcError> for Error {
107 fn from(e: EthRpcError) -> Error {
108 let e: JsonRpcError = error_object_owned_to_jsonrpc_error(e.into());
109 e.into()
110 }
111}
112
113pub(crate) fn invalid_params<T: Debug>(param: &str, details: T) -> Error {
114 Error::JsonRpcError(JsonRpcError {
115 code: ErrorCode::InvalidParams,
116 message: format!("Invalid parameters: {}", param),
117 data: Some(Value::String(format!("{:?}", details))),
118 })
119 .into()
120}
121
122pub(crate) fn invalid_params_check<T, E: Display>(
123 param: &str, r: std::result::Result<T, E>,
124) -> Result<T> {
125 match r {
126 Ok(t) => Ok(t),
127 Err(e) => {
128 Err(Error::InvalidParam(param.into(), format!("{}", e)).into())
129 }
130 }
131}
132
133pub fn account_result_to_rpc_result<T>(
134 param: &str, result: std::result::Result<T, AccountError>,
135) -> Result<T> {
136 match result {
137 Ok(t) => Ok(t),
138 Err(AccountError::InvalidRlp(decoder_error)) => {
139 Err(decoder_error.into())
140 }
141 Err(e) => Err(invalid_params(param, format!("{}", e))),
142 }
143}