cfxcore/
errors.rs

1// Copyright 2020 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4use 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            // TODO(thegaram): consider returning InvalidParams instead
58            | Error::FilterError(_)
59
60            // TODO(thegaram): make error conversion more fine-grained here
61            | 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}