Wednesday, September 15, 2010

Re: Unchecked exceptions from server to client

> Its a feature, not a defect.

You are quite right.

> You have to explicitly declare any methods you want to send to the client. Without this declaration, GWT would have had to create javascript code for every RuntimeException in the system - and that would certainly lead to code bloat.

True - I wonder if there is another solution. Like a special
GWTRuntimeException you can extend into your own exceptions, so GWT
knows only to generate javascript code for them ?

How does that sound ?


On Thu, Sep 16, 2010 at 8:21 AM, Sripathi Krishnan
<sripathi.krishnan@gmail.com> wrote:
>>
>> Does anyone have a reason for why I should not report this a bug in the issue tracker ?
>
> Its a feature, not a defect.
> You have to explicitly declare any methods you want to send to the client. Without this declaration, GWT would have had to create javascript code for every RuntimeException in the system - and that would certainly lead to code bloat.
> --Sri
>
>
> On 16 September 2010 11:26, Kasper Hansen <kbhdk1976@gmail.com> wrote:
>>
>> After closer examination, this solution is not good enough. Examine the stacktrace below;
>>
>> SEVERE: [1284616090213000] javax.servlet.ServletContext log: Exception while dispatching incoming RPC call
>>
>> com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract void com.netgazelle.client.service.AccountService.createAccount(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.Date,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws com.netgazelle.shared.CreateException' threw an unexpected exception: com.netgazelle.shared.DuplicatePhoneCreationException
>>
>> at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:378)
>>
>> at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:581)
>>
>> at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:188)
>>
>> at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:224)
>>
>> at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
>>
>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
>>
>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
>>
>> at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
>>
>> at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
>>
>> at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:58)
>>
>> at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>
>> at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
>>
>> at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>
>> at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
>>
>> at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
>>
>> at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
>>
>> at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>>
>> at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
>>
>> at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>>
>> at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
>>
>> at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
>>
>> at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>
>> at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:349)
>>
>> at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>>
>> at org.mortbay.jetty.Server.handle(Server.java:326)
>>
>> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
>>
>> at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
>>
>> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
>>
>> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
>>
>> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>>
>> at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
>>
>> at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
>>
>> Caused by: com.netgazelle.shared.DuplicatePhoneCreationException
>>
>> at com.netgazelle.server.manager.AccountManager.createAccount(AccountManager.java:285)
>>
>> at com.netgazelle.server.service.AccountServiceImpl.createAccount(AccountServiceImpl.java:74)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>
>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>
>> at java.lang.reflect.Method.invoke(Method.java:597)
>>
>> at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:100)
>>
>> at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:562)
>>
>> ... 30 more
>>
>> My problem lies in RPC.java line 377; !RPCServletUtils.isExpectedException(serviceMethod, cause))
>> The function RPCServletUtils.isExpectedException does not take this into consideration;
>> --> if the cause is an unchecked exception
>> --> if the cuase is an subclass instance of an defined and checked exception
>> The workaround seems to be to define the explicit exceptions throws in the service interface.
>> Does anyone have a reason for why I should not report this a bug in the issue tracker ?
>> Thanks,
>> :-) Kasper
>> On Tue, Sep 14, 2010 at 8:50 AM, San0 <sanopl@gmail.com> wrote:
>> > Your service probably extends RemoteServiceServlet, which is catching
>> > all non declared exceptions. Simple solution is to create your own
>> > RemoteServiceServlet implementation with overridden:
>> > String processCall(String payload) throws SerializationException
>> > Something like this:
>> >
>> > try {
>> >      RPCRequest rpcRequest = RPC.decodeRequest(payload,
>> > delegate.getClass(), this);
>> >      onAfterRequestDeserialized(rpcRequest);
>> >      return RPC.invokeAndEncodeResponse(delegate,
>> > rpcRequest.getMethod(),
>> >          rpcRequest.getParameters(),
>> > rpcRequest.getSerializationPolicy(),
>> >          rpcRequest.getFlags());
>> >    } catch (IncompatibleRemoteServiceException ex) {
>> >      log("An IncompatibleRemoteServiceException was thrown while
>> > processing this call.",ex);
>> >      return RPC.encodeResponseForFailure(null, ex);
>> >    } catch (Exception ex) {
>> >      // RuntimeException
>> >      return RPC.encodeResponseForFailure(null, new
>> > GwtClientException(ex.getCause().getMessage()));
>> >    }
>> >
>> > try-catch is from GWT sources, 2nd catch is what u need to re-throw
>> > exceptions to client.
>> >
>> > On Sep 13, 9:24 pm, Kasper Hansen <kbhdk1...@gmail.com> wrote:
>> >> Hi,
>> >>
>> >> I have this;
>> >>
>> >> public abstract class CreateException extends RuntimeException implements
>> >> Serializable {
>> >>
>> >> }
>> >>
>> >> Notice that I extend from RuntimeException, making it an unchecked
>> >> exception.
>> >>
>> >> Then I have these two;
>> >>
>> >> public class DuplicateEmailCreationException extends CreateException {
>> >>
>> >> }
>> >>
>> >> public class DuplicatePhoneCreationException extends CreateException {
>> >>
>> >> }
>> >>
>> >> My service is this one;
>> >>
>> >> @RemoteServiceRelativePath("AccountService")
>> >> public interface AccountService extends RemoteService {
>> >>
>> >> public void createAccount(String phone, String email);
>> >>
>> >> }
>> >>
>> >> Notice I don't declare my CreateException using the "throws" keyword.
>> >>
>> >> Now I would expect my view to work. It's this one;
>> >>
>> >> ...
>> >> accountServiceAsync.createAccount(tbPhone.getValue(), tbEmail.getValue(),
>> >> new AsyncCallback<Void>() {
>> >>
>> >> public void onSuccess(Void result) {
>> >>
>> >> }
>> >>
>> >> public void onFailure(Throwable exception) {
>> >>
>> >> if ( exception instanceof DuplicatePhoneCreationException) {
>> >>
>> >> // handle it
>> >>
>> >> }
>> >>
>> >> else {
>> >>
>> >> if (exception instanceof DuplicateEmailCreationException) {
>> >>
>> >> // handle it
>> >>
>> >> }
>> >> }
>> >> }
>> >>
>> >> ...
>> >>
>> >> However, it does not work. But if I add the "throws CreateException" in the
>> >> AccountService's createAccount method, it works fine.
>> >>
>> >> The whole point with unchecked exceptions, is that I don't have to define
>> >> them everywhere. Is this not supported ? Or what am I doing wrong here ?
>> >>
>> >> Thanks,
>> >>
>> >> :-) Kasper
>> >
>> > --
>> > You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
>> > To post to this group, send email to google-web-toolkit@googlegroups.com.
>> > To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
>> > For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>> >
>> >
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
>> To post to this group, send email to google-web-toolkit@googlegroups.com.
>> To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
>> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To post to this group, send email to google-web-toolkit@googlegroups.com.
> To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To post to this group, send email to google-web-toolkit@googlegroups.com.
To unsubscribe from this group, send email to google-web-toolkit+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

No comments:

Post a Comment