From 1e01ca082c15887ae3e551b569a9a5a393748b08 Mon Sep 17 00:00:00 2001 From: Bart Platak Date: Thu, 24 Jul 2025 22:37:49 +0100 Subject: [PATCH] update error response --- lazer/sdk/rust/protocol/src/jrpc.rs | 119 +++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 12 deletions(-) diff --git a/lazer/sdk/rust/protocol/src/jrpc.rs b/lazer/sdk/rust/protocol/src/jrpc.rs index 5dca3e6362..ff01907535 100644 --- a/lazer/sdk/rust/protocol/src/jrpc.rs +++ b/lazer/sdk/rust/protocol/src/jrpc.rs @@ -9,7 +9,7 @@ pub struct PythLazerAgentJrpcV1 { pub jsonrpc: JsonRpcVersion, #[serde(flatten)] pub params: JrpcCall, - pub id: i64, + pub id: Option, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] @@ -20,14 +20,14 @@ pub enum JrpcCall { GetMetadata(GetMetadataParams), } -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] pub struct FeedUpdateParams { pub feed_id: PriceFeedId, pub source_timestamp: TimestampUs, pub update: UpdateParams, } -#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] #[serde(tag = "type")] pub enum UpdateParams { #[serde(rename = "price")] @@ -59,6 +59,7 @@ pub enum JsonRpcVersion { } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +#[serde(untagged)] pub enum JrpcResponse { Success(JrpcSuccessResponse), Error(JrpcErrorResponse), @@ -89,7 +90,8 @@ pub struct JrpcErrorObject { #[derive(Debug, Eq, PartialEq)] pub enum JrpcError { ParseError(String), - InternalError, + InternalError(String), + SendUpdateError(FeedUpdateParams), } // note: error codes can be found in the rfc https://www.jsonrpc.org/specification#error_object @@ -101,10 +103,15 @@ impl From for JrpcErrorObject { message: "Parse error".to_string(), data: Some(error_message.into()), }, - JrpcError::InternalError => JrpcErrorObject { + JrpcError::InternalError(error_message) => JrpcErrorObject { code: -32603, message: "Internal error".to_string(), - data: None, + data: Some(error_message.into()), + }, + JrpcError::SendUpdateError(feed_update_params) => JrpcErrorObject { + code: -32000, + message: "Internal error".to_string(), + data: Some(serde_json::to_value(feed_update_params).unwrap()), }, } } @@ -165,7 +172,47 @@ mod tests { best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()), }, }), - id: 1, + id: Some(1), + }; + + assert_eq!( + serde_json::from_str::(json).unwrap(), + expected + ); + } + + #[test] + fn test_push_update_price_without_id() { + let json = r#" + { + "jsonrpc": "2.0", + "method": "push_update", + "params": { + "feed_id": 1, + "source_timestamp": 745214124124, + + "update": { + "type": "price", + "price": 5432, + "best_bid_price": 5432, + "best_ask_price": 5432 + } + } + } + "#; + + let expected = PythLazerAgentJrpcV1 { + jsonrpc: JsonRpcVersion::V2, + params: PushUpdate(FeedUpdateParams { + feed_id: PriceFeedId(1), + source_timestamp: TimestampUs::from_micros(745214124124), + update: UpdateParams::PriceUpdate { + price: Price::from_integer(5432, 0).unwrap(), + best_bid_price: Some(Price::from_integer(5432, 0).unwrap()), + best_ask_price: Some(Price::from_integer(5432, 0).unwrap()), + }, + }), + id: None, }; assert_eq!( @@ -204,7 +251,7 @@ mod tests { best_ask_price: None, }, }), - id: 1, + id: Some(1), }; assert_eq!( @@ -243,7 +290,7 @@ mod tests { rate: Rate::from_integer(1234567891, 0).unwrap(), }, }), - id: 1, + id: Some(1), }; assert_eq!( @@ -280,7 +327,7 @@ mod tests { rate: Rate::from_integer(1234567891, 0).unwrap(), }, }), - id: 1, + id: Some(1), }; assert_eq!( @@ -309,7 +356,7 @@ mod tests { names: Some(vec!["BTC/USD".to_string()]), asset_types: Some(vec!["crypto".to_string()]), }), - id: 1, + id: Some(1), }; assert_eq!( @@ -335,7 +382,7 @@ mod tests { names: None, asset_types: None, }), - id: 1, + id: Some(1), }; assert_eq!( @@ -396,4 +443,52 @@ mod tests { } ); } + + #[test] + pub fn test_parse_response() { + let success_response = serde_json::from_str::>( + r#" + { + "jsonrpc": "2.0", + "id": 2, + "result": "success" + }"#, + ) + .unwrap(); + + assert_eq!( + success_response, + JrpcResponse::Success(JrpcSuccessResponse:: { + jsonrpc: JsonRpcVersion::V2, + result: "success".to_string(), + id: 2, + }) + ); + + let error_response = serde_json::from_str::>( + r#" + { + "jsonrpc": "2.0", + "id": 3, + "error": { + "code": -32603, + "message": "Internal error" + } + }"#, + ) + .unwrap(); + + assert_eq!( + error_response, + JrpcResponse::Error(JrpcErrorResponse { + jsonrpc: JsonRpcVersion::V2, + error: JrpcErrorObject { + code: -32603, + message: "Internal error".to_string(), + data: None, + }, + id: Some(3), + }) + ); + } }