From 8b65edf8ce083cd0239d6c2ffb0d6dc1a4bfd042 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Tue, 29 Jun 2021 15:28:13 +0200 Subject: [PATCH] feat: customizable JSON-RPC error codes via new enum variant on `CallErrror` (#394) * feat: customizable error via RpcError trait This commit introduces a new trait for defining user customizable error codes and messages * revert trait stuff * use RawValue * fix docs * rexport to_json_raw_value --- types/src/error.rs | 17 ++++++++++++++--- types/src/lib.rs | 5 ++++- utils/src/server/rpc_module.rs | 22 +++++++++++++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/types/src/error.rs b/types/src/error.rs index 5fe57efadf..7ca23178ad 100644 --- a/types/src/error.rs +++ b/types/src/error.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use serde_json::value::RawValue; use std::fmt; /// Convenience type for displaying errors. @@ -19,12 +20,22 @@ impl fmt::Display for Mismatch { /// Error that occurs when a call failed. #[derive(Debug, thiserror::Error)] pub enum CallError { - #[error("Invalid params in the RPC call")] /// Invalid params in the call. + #[error("Invalid params in the call")] InvalidParams, + /// The call failed (let jsonrpsee assign default error code and error message). #[error("RPC Call failed: {0}")] - /// The call failed. - Failed(#[source] Box), + Failed(Box), + /// Custom error with specific JSON-RPC error code, message and data. + #[error("RPC Call failed: code: {code}, message: {message}, data: {data:?}")] + Custom { + /// JSON-RPC error code + code: i32, + /// Short description of the error. + message: String, + /// A primitive or structured value that contains additional information about the error. + data: Option>, + }, } /// Error type. diff --git a/types/src/lib.rs b/types/src/lib.rs index 9d14f62b92..0009aee4b6 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -24,4 +24,7 @@ pub use beef::Cow; pub use client::*; pub use error::Error; pub use serde::{de::DeserializeOwned, Serialize}; -pub use serde_json::{to_value as to_json_value, value::RawValue as JsonRawValue, Value as JsonValue}; +pub use serde_json::{ + to_value as to_json_value, value::to_raw_value as to_json_raw_value, value::RawValue as JsonRawValue, + Value as JsonValue, +}; diff --git a/utils/src/server/rpc_module.rs b/utils/src/server/rpc_module.rs index f001cf29c1..46995fce72 100644 --- a/utils/src/server/rpc_module.rs +++ b/utils/src/server/rpc_module.rs @@ -69,7 +69,7 @@ impl MethodCallback { if let Err(err) = result { log::error!("execution of method call '{}' failed: {:?}, request id={:?}", req.method, err, id); - send_error(id, &tx, JsonRpcErrorCode::ServerError(-1).into()); + send_error(id, tx, JsonRpcErrorCode::ServerError(-1).into()); } } } @@ -190,14 +190,18 @@ impl RpcModule { match callback(params, &*ctx) { Ok(res) => send_response(id, tx, res), Err(CallError::InvalidParams) => send_error(id, tx, JsonRpcErrorCode::InvalidParams.into()), - Err(CallError::Failed(err)) => { + Err(CallError::Failed(e)) => { let err = JsonRpcErrorObject { code: JsonRpcErrorCode::ServerError(CALL_EXECUTION_FAILED_CODE), - message: &err.to_string(), + message: &e.to_string(), data: None, }; send_error(id, tx, err) } + Err(CallError::Custom { code, message, data }) => { + let err = JsonRpcErrorObject { code: code.into(), message: &message, data: data.as_deref() }; + send_error(id, tx, err) + } }; Ok(()) @@ -227,15 +231,19 @@ impl RpcModule { match callback(params, ctx).await { Ok(res) => send_response(id, &tx, res), Err(CallError::InvalidParams) => send_error(id, &tx, JsonRpcErrorCode::InvalidParams.into()), - Err(CallError::Failed(err)) => { - log::error!("Call failed with: {}", err); + Err(CallError::Failed(e)) => { let err = JsonRpcErrorObject { code: JsonRpcErrorCode::ServerError(CALL_EXECUTION_FAILED_CODE), - message: &err.to_string(), + message: &e.to_string(), data: None, }; send_error(id, &tx, err) } + Err(CallError::Custom { code, message, data }) => { + let err = + JsonRpcErrorObject { code: code.into(), message: &message, data: data.as_deref() }; + send_error(id, &tx, err) + } }; Ok(()) }; @@ -323,7 +331,7 @@ impl RpcModule { MethodCallback::Sync(Arc::new(move |id, params, tx, conn_id| { let sub_id = params.one()?; subscribers.lock().remove(&SubscriptionKey { conn_id, sub_id }); - send_response(id, &tx, "Unsubscribed"); + send_response(id, tx, "Unsubscribed"); Ok(()) })),