use crate::error::error_codes as codes;
use alloy_primitives::hex;
use alloy_rpc_types::error::EthRpcErrorCode;
use cfx_types::H256;
use jsonrpc_core::{Error, ErrorCode, Value};
use jsonrpsee::types::ErrorObjectOwned;
use std::fmt;
pub fn rpc_err(
code: i32, msg: impl Into<String>, data: Option<&[u8]>,
) -> Error {
Error {
code: ErrorCode::from(code as i64),
message: msg.into(),
data: data.map(|v| serde_json::Value::String(hex::encode_prefixed(v))),
}
}
pub fn build_rpc_server_error(code: i64, message: String) -> Error {
Error {
code: ErrorCode::ServerError(code),
message,
data: None,
}
}
pub fn unimplemented(details: Option<String>) -> Error {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED),
message: "This API is not implemented yet".into(),
data: details.map(Value::String),
}
}
pub fn invalid_input_rpc_err(msg: impl Into<String>) -> Error {
rpc_err(EthRpcErrorCode::InvalidInput.code(), msg, None)
}
pub fn invalid_params_rpc_err(msg: impl Into<String>) -> Error {
rpc_err(ErrorCode::InvalidParams.code() as i32, msg, None)
}
pub fn invalid_params<T: fmt::Debug>(param: &str, details: T) -> Error {
Error {
code: ErrorCode::InvalidParams,
message: format!("Invalid parameters: {}", param),
data: Some(Value::String(format!("{:?}", details))),
}
}
pub fn invalid_params_check<T, E: std::fmt::Display>(
param: &str, r: std::result::Result<T, E>,
) -> Result<T, Error> {
match r {
Ok(t) => Ok(t),
Err(e) => Err(invalid_params(param.into(), format!("{}", e)).into()),
}
}
pub fn invalid_params_msg(param: &str) -> Error {
invalid_params_rpc_err(format!("Invalid parameters: {}", param))
}
pub fn invalid_params_detail<T: fmt::Debug>(param: &str, details: T) -> Error {
Error {
code: ErrorCode::InvalidParams,
message: format!("Invalid parameters: {} {:?}", param, details),
data: Some(Value::String(format!("{:?}", details))),
}
}
pub fn unknown_block() -> Error {
Error {
code: ErrorCode::InvalidParams,
message: "Unknown block number".into(),
data: None,
}
}
pub fn internal_rpc_err(msg: impl Into<String>) -> Error {
rpc_err(ErrorCode::InternalError.code() as i32, msg, None)
}
pub fn internal_rpc_err_with_data(
msg: impl Into<String>, data: &[u8],
) -> Error {
rpc_err(ErrorCode::InternalError.code() as i32, msg, Some(data))
}
pub fn internal_error_msg(param: &str) -> Error {
Error {
code: ErrorCode::InternalError,
message: format!("Internal error: {}", param),
data: None,
}
}
pub fn internal_error<T: fmt::Debug>(details: T) -> Error {
Error {
code: ErrorCode::InternalError,
message: "Internal error".into(),
data: Some(Value::String(format!("{:?}", details))),
}
}
pub fn call_execution_error(message: String, data: String) -> Error {
Error {
code: ErrorCode::ServerError(codes::CALL_EXECUTION_ERROR),
message,
data: Some(Value::String(data)),
}
}
pub fn geth_call_execution_error(message: String, data: String) -> Error {
Error {
code: ErrorCode::ServerError(
EthRpcErrorCode::ExecutionError.code() as i64
),
message,
data: Some(Value::String(data)),
}
}
pub fn request_rejected_too_many_request_error(
details: Option<String>,
) -> Error {
Error {
code: ErrorCode::ServerError(codes::REQUEST_REJECTED_TOO_MANY_REQUESTS),
message: "Request rejected.".into(),
data: details.map(Value::String),
}
}
pub fn request_rejected_in_catch_up_mode(details: Option<String>) -> Error {
Error {
code: ErrorCode::ServerError(codes::REQUEST_REJECTED_IN_CATCH_UP),
message: "Request rejected due to still in the catch up mode.".into(),
data: details.map(Value::String),
}
}
pub fn pivot_assumption_failed(expected: H256, got: H256) -> Error {
Error {
code: ErrorCode::ServerError(codes::CONFLUX_PIVOT_CHAIN_UNSTABLE),
message: "pivot chain assumption failed".into(),
data: Some(Value::String(format!(
"pivot assumption: {:?}, actual pivot hash: {:?}",
expected, got
))),
}
}
pub fn error_object_owned_to_jsonrpc_error(e: ErrorObjectOwned) -> Error {
Error {
code: ErrorCode::from(e.code() as i64),
message: e.message().into(),
data: e.data().map(|v| Value::String(v.to_string())),
}
}