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