From 1fb61acff0f4264a1e996d143f17ae5e89849ec7 Mon Sep 17 00:00:00 2001 From: Tom Anderson Date: Mon, 24 Jun 2024 11:46:29 +1000 Subject: [PATCH] return parameter deserialisation errors (close #69) --- .changes/return-param-errors.md | 6 ++++++ crates/qubit-macros/src/handler/mod.rs | 8 ++++++-- src/builder/mod.rs | 3 +++ src/builder/rpc_builder.rs | 17 ++++++++++------- 4 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 .changes/return-param-errors.md diff --git a/.changes/return-param-errors.md b/.changes/return-param-errors.md new file mode 100644 index 0000000..3f67bd8 --- /dev/null +++ b/.changes/return-param-errors.md @@ -0,0 +1,6 @@ +--- +"qubit": patch:feat +"qubit-macros": patch:feat +--- + +return parameter deserialising errors if they are encountered (close #69) diff --git a/crates/qubit-macros/src/handler/mod.rs b/crates/qubit-macros/src/handler/mod.rs index c5e8350..9a3e1a7 100644 --- a/crates/qubit-macros/src/handler/mod.rs +++ b/crates/qubit-macros/src/handler/mod.rs @@ -237,7 +237,10 @@ impl From for TokenStream { // Generate the parameter parsing implementation let parse_params = (!inputs.is_empty()).then(|| { quote! { - let (#(#param_names,)*) = #params_ident.parse::<(#(#param_tys,)*)>().unwrap(); + let (#(#param_names,)*) = match #params_ident.parse::<(#(#param_tys,)*)>() { + ::std::result::Result::Ok(params) => params, + ::std::result::Result::Err(e) => return ::std::result::Result::Err(e), + }; } }); @@ -251,7 +254,8 @@ impl From for TokenStream { let register_inner = quote! { #parse_params - #handler_call + let result = #handler_call; + ::std::result::Result::Ok::<_, ::qubit::ErrorObject>(result) }; let register_method = match kind { diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 81c8c8c..f807379 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -9,3 +9,6 @@ pub use handler::Handler; pub(crate) use handler::HandlerCallbacks; pub use rpc_builder::RpcBuilder; pub use ty::*; + +pub use jsonrpsee::types::ErrorObject; +pub use jsonrpsee::IntoResponse; diff --git a/src/builder/rpc_builder.rs b/src/builder/rpc_builder.rs index 0eef4d4..55ed5d8 100644 --- a/src/builder/rpc_builder.rs +++ b/src/builder/rpc_builder.rs @@ -2,10 +2,10 @@ use std::ops::Deref; use futures::{Future, Stream, StreamExt}; use jsonrpsee::{ - types::{ErrorCode, Params, ResponsePayload}, - RpcModule, SubscriptionCloseResponse, SubscriptionMessage, + types::{ErrorCode, ErrorObject, Params, ResponsePayload}, + IntoResponse, RpcModule, SubscriptionCloseResponse, SubscriptionMessage, }; -use serde::Serialize; +use serde::{de::Error, Serialize}; use serde_json::json; use crate::{FromRequestExtensions, RequestKind, RpcError}; @@ -50,7 +50,7 @@ where T: Serialize + Clone + 'static, C: FromRequestExtensions, F: Fn(C, Params<'static>) -> Fut + Send + Sync + Clone + 'static, - Fut: Future + Send + 'static, + Fut: Future>> + Send + 'static, { self.register_handler(name, handler, RequestKind::Query) } @@ -61,7 +61,7 @@ where T: Serialize + Clone + 'static, C: FromRequestExtensions, F: Fn(C, Params<'static>) -> Fut + Send + Sync + Clone + 'static, - Fut: Future + Send + 'static, + Fut: Future>> + Send + 'static, { self.register_handler(name, handler, RequestKind::Mutation) } @@ -78,7 +78,7 @@ where T: Serialize + Clone + 'static, C: FromRequestExtensions, F: Fn(C, Params<'static>) -> Fut + Send + Sync + Clone + 'static, - Fut: Future + Send + 'static, + Fut: Future>> + Send + 'static, { self.module .register_async_method(self.namespace_str(name), move |params, ctx, extensions| { @@ -114,7 +114,10 @@ where }; // Run the actual handler - ResponsePayload::success(handler(ctx, params).await) + match handler(ctx, params).await { + Ok(result) => ResponsePayload::success(result), + Err(e) => ResponsePayload::error(e), + } } }) .unwrap();