I’ve set up an RPCHandler like in the Ignition Programmer’s Guide. If I try to throw an exception to be caught on a component from the RPCHandler then things go wrong. Both on the RPCHandler and on the interface it implements I’ve specified “throws MyException”. I think at some point my thrown exception gets wrapped as a GatewayException. I’m guessing because my RPCHandler doesn’t specify that it throws GatewayExceptions (which I don’t think it’s even possible for it throw a gateway exception because GatewayException is defined in client scope), the GatewayException is then wrapped in an UndeclaredThrowableException. How can I get my original exception back to the function caller without unwrapping all the layers?
I don’t think custom exception types can be propagated from gateway to client/designer through the module RPC system. Any exceptions caught have their cause, message, stack trace… extracted and sent to the client, where it re-assembles it as a new Throwable that I think you can find embedded in the GatewayException.
I think this all happens mostly due to some complex serialization issues.
I see. Is it possible to specify all my functions in the RPCHandler throw GatewayExceptions so I can at least avoid the UndeclaredThrowableException? I tried to import com.inductiveautomation.ignition.client.gateway_interface.GatewayException but the gateway complains it can’t be found. Is it a good idea to try to import GatewayException into my RPCHandler and see if I can adjust the build to make it work? Or is there some other way?
Assuming I can get the functions in my RPCHandler to throw GatewayExceptions, would you catch gatewayexceptions with something like this:
try{
rpc.doStuff()
} catch(GatewayException e){
if(e.getCause()!=null){
if(e.getCause() is MyException){
//handle MyException
}
else if (e.getCause() is MyOtherException){
//handle MyOtherException
}
}
}
I’m not quite sure where the UndeclaredThrowableException is coming from - I don’t think it’s us.
If you change your handler so it just throws a vanilla Exception what happens?
Kevin, you are correct. The UndeclaredThrowable isn’t from you guys (edit: not directly at least).
My function signature is:
void doStuff() throws MyException;
When calling rpc.doStuff(), java expects that it won’t throw a GatewayException so when it does throw a GatewayException, it wraps it in UndeclaredThrowableException.
I want my function’s signature to be:
void doStuff() throws GatewayException;
But I believe I cannot do that because GatewayException is a client-side thing.
And throwing Exception I think is considered bad practice because then anywhere that I call rpc.doStuff(), I either have to rethrow Exception everywhere or catch the original and throw a runtime Exception instead.
EDIT: I should add that throwing Exception does indeed stop the UndeclaredThrowableException, but it’s not ideal.
It’s not ideal, but I think it’s all get you get with the RPC system - either your functions don’t throw at all, or they throw a generic Exception.
I figured that might be the case . Thanks for your help though
One other workaround, kind of a hack, but still: Never throw from the RPC calls, and instead return a “result” object of your own creation, that can hold both a good/success result and a throwable/exception in the case of failure. The throwable inside your result object will not be touched by the RPC and serialization logic.