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