Skip to content

Method parameter conversion error handling logic should preserve JSON-RPC id from the request #290

@cyb3r4nt

Description

@cyb3r4nt

During upgrade to newer 1.6.0 version an error related to invalid handling of JSON-RPC id was discovered.

Suppose you have a server with following interface:

public interface ServiceInterfaceWithParamNameAnnotation {
	String methodWithDifferentTypes(
		@JsonRpcParam("param1") Boolean booleanParam1,
		@JsonRpcParam("param2") Double doubleParam2,
		@JsonRpcParam("param3") UUID doubleParam3
	);
}

When a valid json, but with invalid parameters, is sent to server:

{"method":"methodWithDifferentTypes","id":4,"jsonrpc":"2.0","params":[true,3.14,"iWantToBeAnUUID"]} 

Then server responds with

 {"jsonrpc":"2.0","id":"null","error":{"code":-32700,"message":"JSON parse error"}} 

, where initial id value is lost.

This is also true for the batch requests, where multiple requests are sent at once.
It should be possible to find a failed request by id from the response.

The "JSON parse error" -32700 is not really correct here because:

  • input is a valid JSON-RPC object
  • method exists
  • parameter count is correct

Valid error probably should be the "Invalid params" -32602 , because wrong parameter was sent.

More detailed log (code line numbers may be wrong):

2022-06-11 01:33:06,940 DEBUG c.g.j.JsonRpcBasicServer:109 [Test worker] created server for interface interface com.googlecode.jsonrpc4j.server.JsonRpcServerAnnotatedParamTest$ServiceInterfaceWithParamNameAnnotation with handler class com.sun.proxy.$Proxy13 
2022-06-11 01:33:07,025 DEBUG c.g.j.JsonRpcBasicServer:420 [Test worker] Request: {"method":"methodWithDifferentTypes","id":4,"jsonrpc":"2.0","params":[true,3.14,"iWantToBeAnUUID"]} 
2022-06-11 01:33:07,075 DEBUG c.g.j.JsonRpcBasicServer:585 [Test worker] Invoking method: methodWithDifferentTypes with args [true, 3.14, "iWantToBeAnUUID"] 
2022-06-11 01:33:07,097 DEBUG c.g.j.JsonRpcBasicServer:1011 [Test worker] Response: {"jsonrpc":"2.0","id":"null","error":{"code":-32700,"message":"JSON parse error"}} 

Variant with batching:

2022-06-11 02:03:41,279 DEBUG c.g.j.JsonRpcBasicServer:109 [Test worker] created server for interface interface com.googlecode.jsonrpc4j.server.JsonRpcServerTest$ServiceInterface with handler class com.sun.proxy.$Proxy13 
2022-06-11 02:03:41,294 DEBUG c.g.j.JsonRpcBasicServer:109 [Test worker] created server for interface interface com.googlecode.jsonrpc4j.server.JsonRpcServerAnnotatedParamTest$ServiceInterfaceWithParamNameAnnotation with handler class com.sun.proxy.$Proxy28 
2022-06-11 02:03:41,456 DEBUG c.g.j.JsonRpcServer:115 [Test worker] Handling HttpServletRequest org.springframework.mock.web.MockHttpServletRequest@1578104e 
2022-06-11 02:03:41,500 DEBUG c.g.j.JsonRpcBasicServer:303 [Test worker] Handling 3 requests 
2022-06-11 02:03:41,501 DEBUG c.g.j.JsonRpcBasicServer:420 [Test worker] Request: {"method":"methodWithDifferentTypes","id":1,"jsonrpc":"2.0","params":[true,3.14,"cbddeb26-ea0c-48f9-adeb-5b28158fc71c"]} 
2022-06-11 02:03:41,523 DEBUG c.g.j.JsonRpcBasicServer:585 [Test worker] Invoking method: methodWithDifferentTypes with args [true, 3.14, "cbddeb26-ea0c-48f9-adeb-5b28158fc71c"] 
2022-06-11 02:03:41,550 DEBUG c.g.j.JsonRpcBasicServer:602 [Test worker] Invoked method: methodWithDifferentTypes, result passResult1 
2022-06-11 02:03:41,557 DEBUG c.g.j.JsonRpcBasicServer:420 [Test worker] Request: {"method":"methodWithDifferentTypes","id":2,"jsonrpc":"2.0","params":["truth",3.14,"e43f3ef3-88c4-4ded-9be0-8efaecd3c1dc"]} 
2022-06-11 02:03:41,557 DEBUG c.g.j.JsonRpcBasicServer:585 [Test worker] Invoking method: methodWithDifferentTypes with args ["truth", 3.14, "e43f3ef3-88c4-4ded-9be0-8efaecd3c1dc"] 
2022-06-11 02:03:41,559 DEBUG c.g.j.JsonRpcBasicServer:420 [Test worker] Request: {"method":"methodWithDifferentTypes","id":3,"jsonrpc":"2.0","params":[true,3.14,"cbddeb26-ea0c-48f9-adeb-5b28158fc71c"]} 
2022-06-11 02:03:41,559 DEBUG c.g.j.JsonRpcBasicServer:585 [Test worker] Invoking method: methodWithDifferentTypes with args [true, 3.14, "cbddeb26-ea0c-48f9-adeb-5b28158fc71c"] 
2022-06-11 02:03:41,560 DEBUG c.g.j.JsonRpcBasicServer:602 [Test worker] Invoked method: methodWithDifferentTypes, result passResult3 
2022-06-11 02:03:41,561 DEBUG c.g.j.JsonRpcBasicServer:339 [Test worker] served 3 requests, error 1, result JsonError{code=-32002, message='bulk error', data=null} 
2022-06-11 02:03:41,561 DEBUG c.g.j.JsonRpcBasicServer:1011 [Test worker] Response: [{"jsonrpc":"2.0","id":1,"result":"passResult1"},{"jsonrpc":"2.0","id":"null","error":{"code":-32700,"message":"JSON parse error"}},{"jsonrpc":"2.0","id":3,"result":"passResult3"}] 

The behavior was correct in previous 1.5.3 version, but in 1.6.0 server started to output null values for id in responses.
This is caused by the recent change in the error handling logic:
https://github.com/briandilley/jsonrpc4j/blob/1.6.0/src/main/java/com/googlecode/jsonrpc4j/JsonRpcBasicServer.java#L466

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions