Skip to content

Commit

Permalink
feat: customizable JSON-RPC error codes via new enum variant on `Call…
Browse files Browse the repository at this point in the history
…Errror` (#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
  • Loading branch information
niklasad1 authored Jun 29, 2021
1 parent 2ca8355 commit 8b65edf
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
17 changes: 14 additions & 3 deletions types/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;
use std::fmt;

/// Convenience type for displaying errors.
Expand All @@ -19,12 +20,22 @@ impl<T: fmt::Display> fmt::Display for Mismatch<T> {
/// 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<dyn std::error::Error + Send + Sync>),
Failed(Box<dyn std::error::Error + Send + Sync>),
/// 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<Box<RawValue>>,
},
}

/// Error type.
Expand Down
5 changes: 4 additions & 1 deletion types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
22 changes: 15 additions & 7 deletions utils/src/server/rpc_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Expand Down Expand Up @@ -190,14 +190,18 @@ impl<Context: Send + Sync + 'static> RpcModule<Context> {
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(())
Expand Down Expand Up @@ -227,15 +231,19 @@ impl<Context: Send + Sync + 'static> RpcModule<Context> {
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(())
};
Expand Down Expand Up @@ -323,7 +331,7 @@ impl<Context: Send + Sync + 'static> RpcModule<Context> {
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(())
})),
Expand Down

0 comments on commit 8b65edf

Please sign in to comment.