jnan77 / jsonrpc4j

Automatically exported from code.google.com/p/jsonrpc4j
0 stars 0 forks source link

Proxied Client to throw checked exception defined on the service interface #20

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Created a checked Exception.
2. Added a throws clause to the service interface.
3. Business logic in the service implementation may throw that checked 
exception.
4. Service is exposed via JsonServiceExporter.
5. Client defined on a totally different project uses JsonProxyFactoryBean.
6. The proxied service API is invoked. A try-catch statement is present for the 
checked exception that may be thrown.

What is the expected output? What do you see instead?
If the service interface is used, it'd be nice if the same checked exception 
would be translated and re-thrown on the proxied instance in case of errors. 
Currently a java.lang.reflect.UndeclaredThrowableException containing the 
java.lang.Exception that contains the actual error message is thrown.

What version of the product are you using? On what operating system?
0.20, GNU Linux

Please provide any additional information below.
Several services will interact with each other so the idea would be to be 
consistent with the API contract as far as exception handling.

Original issue reported on code.google.com by jorge.he...@gmail.com on 5 Mar 2012 at 7:58

GoogleCodeExporter commented 8 years ago

Original comment by brian.di...@gmail.com on 6 Mar 2012 at 2:27

GoogleCodeExporter commented 8 years ago
I've addressed this issue by adding an "ExceptionResolver" interface that the 
client uses to turn server errors into actual exceptions for throwing.

I created an ErrorResolver for the JsonRpcServer that adds type information to 
the "data" part of the json-rpc response.  It is configured by default and runs 
only if the AnnotationsErrorResolver doesn't first resolve the error.

I also changed the AnnotationsErrorResolver so that it too adds type 
information to the "data" part of the json-rpc response.

I also created a "DefaultExceptionResolver" that is configured by default for 
the client that uses type information returned by the DefaultErrorResolver and 
AnnotationsErrorResolver to resolve and throw the same Exceptions that are 
thrown by the server.

The client has the following limitations:
1) constructor must have 0 arguments, or a single argument for a message
2) UndeclaredThrowableException is thrown if an exception other than what is 
defined on the service interface is thrown (obviously polymorphism works here). 
This is a result of using the JDK dynamic proxies.

Please try the latest 0.21-SNAPSHOT version and see how it works for you 
(obviously you'll need the latest version on both the server and client).  If 
you find everything to be working for you then I'll cut a release.

Original comment by brian.di...@gmail.com on 6 Mar 2012 at 2:50

GoogleCodeExporter commented 8 years ago
Hello Brian,

It seems it worked fine for me. At first, my Exception had only the 
MyException(String msg) constructor and I was getting a 
NoSuchMethodException<init()> but as soon as I added the default 0-arg 
constructor I started receiving MyException on the client. The exception 
message was correctly passed from the server to the client as part of the 
MyException object.

I just have a question, there may be other non-java clients accessing this 
JSON-RPC service. They will still see the "error":{"code":"-1", "message":"my 
error message"} in the JSON response, right?

Thanks!

Original comment by jorge.he...@gmail.com on 6 Mar 2012 at 5:50

GoogleCodeExporter commented 8 years ago
Yes, they should.  The message from the exception should be on the 
error.message and error.data.message field.

I didn't quite understand your first sentence there - was it correctly finding 
the constructor?

Original comment by brian.di...@gmail.com on 6 Mar 2012 at 11:39

GoogleCodeExporter commented 8 years ago
It wasn't until I added the 0-arg constructor (I had the MyException(String 
msg) constructor). Then it worked like a charm.

Original comment by jorge.he...@gmail.com on 7 Mar 2012 at 2:33

GoogleCodeExporter commented 8 years ago

Original comment by brian.di...@gmail.com on 25 May 2012 at 2:51

GoogleCodeExporter commented 8 years ago

Original comment by brian.di...@gmail.com on 26 May 2012 at 2:47