Improves RPC request deserialisation error messaging#851
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
crates/starknet-devnet-server/src/rpc_core/error.rs (1)
46-56: Docstring nit: say “with reason”, not “with a message”.The helper preserves the standard message and places details in
data.reason. Update the comment to avoid confusion.-// Creates a new `InvalidRequest` with a message +// Creates a new `InvalidRequest` with a reason in `data.reason`crates/starknet-devnet-server/src/rpc_handler.rs (1)
70-74: Avoid leaking internal rejection details to clients (optional).
err.to_string()in the fallback can expose framework internals. Consider returninginvalid_request()without a reason, and keep the detailedwarn!log.- warn!(target: "rpc", "Request rejection: {}", err); - Response::error(RpcError::invalid_request_with_reason(err.to_string())).into() + warn!(target: "rpc", "Request rejection: {}", err); + Response::error(RpcError::invalid_request()).into()tests/integration/test_websocket.rs (1)
113-132: Make the test robust and check send result.
- Assert
ws.send(...)succeeds (currently ignored).- Avoid strict equality on the entire JSON; assert structure/fields to prevent brittleness if serde error wording changes subtly.
- let _ = - ws.send(tokio_tungstenite::tungstenite::Message::Text("garbage_string".to_string())).await; - - let resp_raw = ws.next().await.unwrap().unwrap(); - let resp: serde_json::Value = serde_json::from_slice(&resp_raw.into_data()).unwrap(); - assert_eq!( - resp, - json!({ - "jsonrpc": "2.0", - "id": serde_json::Value::Null, - "error": { "code": -32700, "message": "Parse error", "data": {"reason" : "expected value at line 1 column 1"} } - }) - ); + ws.send(tokio_tungstenite::tungstenite::Message::Text("garbage_string".to_string())) + .await + .expect("ws send failed"); + + let resp_raw = ws.next().await.unwrap().unwrap(); + let resp: serde_json::Value = serde_json::from_slice(&resp_raw.into_data()).unwrap(); + assert_eq!(resp["jsonrpc"], "2.0"); + assert_eq!(resp["id"], serde_json::Value::Null); + assert_eq!(resp["error"]["code"], -32700); + assert_eq!(resp["error"]["message"], "Parse error"); + assert!(resp["error"]["data"]["reason"] + .as_str() + .unwrap() + .contains("expected value"));crates/starknet-devnet-server/src/api/json_rpc_handler.rs (2)
36-36: Import nit: narrow the import to Id if that’s all you need.Minor readability: import
Iddirectly instead of the wholerpc_corefor this use.-use crate::{ServerConfig, rpc_core}; +use crate::ServerConfig; +use crate::rpc_core::request::Id;Then:
- rpc_core::request::Id::Null + Id::Null
535-540: Tiny optimization: avoid json! round-trip when serializing.Serialize the struct directly; it skips the intermediate
Value.- Err(e) => json!(RpcResponse::from_rpc_error( - RpcError::parse_error(e.to_string()), - rpc_core::request::Id::Null - )) - .to_string(), + Err(e) => serde_json::to_string(&RpcResponse::from_rpc_error( + RpcError::parse_error(e.to_string()), + Id::Null + )) + .expect("serialize RpcResponse"),tests/integration/general_rpc_tests.rs (1)
128-157: Add HTTP 200 assert for consistency.The other tests assert status; add it here too.
let resp = reqwest::Client::new() .post(format!("{}/rpc", devnet.url)) .header("Content-Type", "application/json") .json(&json!({ "jsonrpc": "2.0", "params": [], "id": 1 })) .send() .await .unwrap(); + assert_eq!(resp.status(), reqwest::StatusCode::OK); let error_resp: serde_json::Value = resp.json().await.unwrap();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
crates/starknet-devnet-server/src/api/json_rpc_handler.rs(3 hunks)crates/starknet-devnet-server/src/rpc_core/error.rs(3 hunks)crates/starknet-devnet-server/src/rpc_handler.rs(1 hunks)tests/integration/general_rpc_tests.rs(1 hunks)tests/integration/test_websocket.rs(2 hunks)
🔇 Additional comments (5)
crates/starknet-devnet-server/src/rpc_core/error.rs (1)
26-35: Breaking change: parse_error now requires a reason; confirm semver/consumers.Changing
pub const fn parse_error() -> Selftopub fn parse_error<R>(reason: R) -> Selfis a public API break. Ensure all internal/external callers are updated and bump the crate version accordingly if published.tests/integration/test_websocket.rs (1)
3-3: LGTM: imports required for ws read/write.crates/starknet-devnet-server/src/api/json_rpc_handler.rs (1)
144-144: Unconditional socket cleanup: good reliability improvement.Removing
socket_idon all exit paths prevents leaked entries. Nice.tests/integration/general_rpc_tests.rs (2)
96-126: Relies on exact axum error text; server code should normalize reason.Current server logic splits by “ at line”, which still leaves details like “: expected value…”. After normalizing the server to a constant reason (see rpc_handler.rs suggestion), this test will pass and remain stable across axum/serde versions.
159-187: LGTM: covers missing content type path and expected shape.
97a9879 to
1a91dd0
Compare
Usage related changes
Improves RPC request deserialisation handling, brings it closer to the client implementations.
Development related changes
N/A
Checklist:
I still need to add tests.
./scripts/format.sh./scripts/clippy_check.sh./scripts/check_unused_deps.sh./scripts/check_spelling.sh./website/README.mdSummary by CodeRabbit
Bug Fixes
Tests