How to wrap each callback in one place to improve error handling

In my GWT application, there are many different asynchronous calls on the server using many different services. To better handle errors, I want to wrap all my callbacks so that I can handle exceptions like InvocationExceptions in one place. The superclass that implements AsyncCallback is not really an option, because that would mean that I would have to change every asynchronous call.

RpcServiceProxy#doCreateRequestCallback() looks like a method to override. Simple enough. I just don't see how to get GWT to use my new class.

Another way to formulate a question would be

How to force GWT to use its own subclass of RpcServiceProxy ?

+4
source share
4 answers

To wrap each AsynCallback<T> that is passed to any RemoteService , you need to override RemoteServiceProxy#doCreateRequestCallback() , because every AsynCallback<T> is passed here before the RPC call.

Here are the steps for doing this:

As pointed out by @ChrisLercher, you need to define your own Proxy Generator for each step when the RemoteService proxy is generated. Start by extending ServiceInterfaceProxyGenerator and overriding #createProxyCreator() .

 /** * This Generator extends the default GWT {@link ServiceInterfaceProxyGenerator} and replaces it in the * co.company.MyModule GWT module for all types that are assignable to * {@link com.google.gwt.user.client.rpc.RemoteService}. Instead of the default GWT {@link ProxyCreator} it provides the * {@link MyProxyCreator}. */ public class MyServiceInterfaceProxyGenerator extends ServiceInterfaceProxyGenerator { @Override protected ProxyCreator createProxyCreator(JClassType remoteService) { return new MyProxyCreator(remoteService); } } 

In your MyModule.gwt.xml use delayed binding to instruct GWT to compile using your Proxy Generator whenever it generates something like RemoteService :

 <generate-with class="com.company.ourapp.rebind.rpc.MyServiceInterfaceProxyGenerator"> <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/> </generate-with> 

Extend ProxyCreator and override #getProxySupertype() . Use it in MyServiceInterfaceProxyGenerator#createProxyCreator() so that you can define a base class for all generated RemoteServiceProxies .

 /** * This proxy creator extends the default GWT {@link ProxyCreator} and replaces {@link RemoteServiceProxy} as base class * of proxies with {@link MyRemoteServiceProxy}. */ public class MyProxyCreator extends ProxyCreator { public MyProxyCreator(JClassType serviceIntf) { super(serviceIntf); } @Override protected Class<? extends RemoteServiceProxy> getProxySupertype() { return MyRemoteServiceProxy.class; } } 

Make sure that both MyProxyCreator and your MyServiceInterfaceProxyGenerator are located in a package that GWT will not compile in javascript. Otherwise, you will see the following error:

 [ERROR] Line XX: No source code is available for type com.google.gwt.user.rebind.rpc.ProxyCreator; did you forget to inherit a required module? 

You are now ready to extend RemoteServiceProxy and override #doCreateRequestCallback() ! Here you can do anything you want and apply it to every callback that is sent to your server. Make sure you add this class and any other class that you use here, in my AsyncCallbackProxy case, so that your client package is compiled.

 /** * The remote service proxy extends default GWT {@link RemoteServiceProxy} and proxies the {@link AsyncCallback} with * the {@link AsyncCallbackProxy}. */ public class MyRemoteServiceProxy extends RemoteServiceProxy { public MyRemoteServiceProxy(String moduleBaseURL, String remoteServiceRelativePath, String serializationPolicyName, Serializer serializer) { super(moduleBaseURL, remoteServiceRelativePath, serializationPolicyName, serializer); } @Override protected <T> RequestCallback doCreateRequestCallback(RequestCallbackAdapter.ResponseReader responseReader, String methodName, RpcStatsContext statsContext, AsyncCallback<T> callback) { return super.doCreateRequestCallback(responseReader, methodName, statsContext, new AsyncCallbackProxy<T>(callback)); } } 

Literature:

+7
source

The type you are looking for is probably RemoteServiceProxy (not RpcServiceProxy ), and I assume that you should start by overriding the default binding in /com/google/gwt/user/RemoteService.gwt.xml (just copy the lines to your own. gwt. xml file and configure):

 <generate-with class="com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator"> <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/> </generate-with> 

There you will find protected Class<? extends RemoteServiceProxy> getProxySupertype() protected Class<? extends RemoteServiceProxy> getProxySupertype() , which you can override to return your own RemoteServiceProxy class.

I have not tried it yet, so this may require several additional steps ...

+2
source

Typically, a path in GWT to handle exceptions that occur in asynchronous processes is through UncaughtExceptionHandler s.

I would use my own handler to handle these exceptions:

 GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { public void onUncaughtException(Throwable e) { if (e instanceof WhateverException) { // handle the exception here } } }); 

Using this, you do not need to subclass anything.

0
source

If by โ€œone placeโ€ you mean โ€œI want to process all errors in one methodโ€, then I suggest either catch and throw things until they are in one place, or create an EventBus , which you basically just send every error. Then you can just bind one handler to this bus, which can handle everything.

0
source

Source: https://habr.com/ru/post/1489056/


All Articles