how to return errors from RequestFactoryServlet?

207 views
Skip to first unread message

KaffeineComa

unread,
Mar 31, 2011, 11:45:42 PM3/31/11
to google-we...@googlegroups.com
Like the asker of this question:


I'd like to be able to return errors to the front-end when RequestFactoryServlet encounters a problem.  Thrown exceptions never seem to result in onFailure() or onViolation() being called. Instead, onSuccess() is called despite the failure.

I also tried setting res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), but that just results in java.lang.IllegalStateException, presumably because super.doPost() has already written to the response. (You might wonder why I'm running code after super.doPost()- it's because I'm committing and closing my EntityManager.) 

What must I do to propagate errors to the front-end? Is there some Exception subclass I should throw?

khiem nguyen

unread,
Apr 1, 2011, 6:55:24 PM4/1/11
to google-we...@googlegroups.com
u can extends requestfactoryservlet to use your exceptionhandler (which creates ServerFailure), (dont forget to put it in web.xml instead of the default requestfactoryservlet)
when u throw exception on server, onFailure will be called, not exactly Exception/Throwable thou.

there's a post about it in this forum already, just try to search.


--
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-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

KaffeineComa

unread,
Apr 1, 2011, 9:08:16 PM4/1/11
to google-we...@googlegroups.com
Hi Khiem, thanks for your reply.

Are you saying that RequestFactoryServlet must be extended, and an ExceptionHandler must be installed somehow? If so, what exactly does the ExceptionHandler need to do? 

My server code is already throwing exceptions; it's just that they're not getting propagated back to my client code.

On the client I have code that does something like:

requestContext.fire(new  Receiver<T>() { 

    public void onSuccess(T response) { 
       // etc. 
    }

      public void onFailure(ServerFailure error)
     {
         // this never gets called
  }
});

I appreciate your suggestion to search the group, but I have done so many times. Something is just broken with Google's new groups UI. I couldn't even find this thread to reply to you (I received your reply in an email); I had to back out of Google Groups and search with google.com, rather than Google Groups. It's really frustrating.

Thanks again.



 


Thomas Broyer

unread,
Apr 1, 2011, 9:27:56 PM4/1/11
to google-we...@googlegroups.com


On Saturday, April 2, 2011 3:08:16 AM UTC+2, KaffeineComa wrote:
Hi Khiem, thanks for your reply.

Are you saying that RequestFactoryServlet must be extended, and an ExceptionHandler must be installed somehow? If so, what exactly does the ExceptionHandler need to do?

Construct a ServerFailure from a given Throwable. You can then pass specific "tokens" that your client code will be able to analyze (if needed), but more importantly, you can tell whether the error should be considered "fatal" or not (default implementation of onFailure in Receiver throws a RuntimeException, but only if the ServerFailure is "fatal", which the DefaultExceptionHandler always produces)
 
My server code is already throwing exceptions; it's just that they're not getting propagated back to my client code.

On the client I have code that does something like:

requestContext.fire(new  Receiver<T>() { 

    public void onSuccess(T response) { 
       // etc. 
    }

      public void onFailure(ServerFailure error)
     {
         // this never gets called
  }
});

Assuming "requestContext" above actually is a Request (not a RequestContext), that's abnormal.

If you're indeed talking about a RequestContext (and your T should be read as Void), then it's the normal behavior: the RequestContext-level Receiver's onFailure will only be called if the server (more or less) failed to deserialize the request or serialize the response. When processing service method invocations, each service method's Receiver's onFailure can be called, independently of the others, and the RequestContext-level Receiver's onSuccess will be called in the end.
Have a look at the doFire method in AbstractRequestContext for the exact details of the client-side processing.
 
I appreciate your suggestion to search the group, but I have done so many times. Something is just broken with Google's new groups UI. I couldn't even find this thread to reply to you (I received your reply in an email); I had to back out of Google Groups and search with google.com, rather than Google Groups. It's really frustrating.

Just so you know: you're not alone!
 

KaffeineComa

unread,
Apr 4, 2011, 9:41:59 AM4/4/11
to google-we...@googlegroups.com
Hi Thomas,

On Friday, April 1, 2011 9:27:56 PM UTC-4, Thomas Broyer wrote:
 
Construct a ServerFailure from a given Throwable. You can then pass specific "tokens" that your client code will be able to analyze (if needed), but more importantly, you can tell whether the error should be considered "fatal" or not (default implementation of onFailure in Receiver throws a RuntimeException, but only if the ServerFailure is "fatal", which the DefaultExceptionHandler always produces)

Wait, so there is already a DefaultExceptionHandler in place? So I *don't* need to install my own handler, construct ServerFailures, etc? 

 
Assuming "requestContext" above actually is a Request (not a RequestContext), that's abnormal.

If you're indeed talking about a RequestContext (and your T should be read as Void), then it's the normal behavior: the RequestContext-level Receiver's onFailure will only be called if the server (more or less) failed to deserialize the request or serialize the response. When processing service method invocations, each service method's Receiver's onFailure can be called, independently of the others, and the RequestContext-level Receiver's onSuccess will be called in the end.


Ah, well that's my problem then. In many cases I'm firing on the context rather than on the request, because I have stacked up multiple calls, and I want them to fire as a group, rather than having to fire them all serially. There was a posting in this group a while back (hah, good luck finding it!) suggesting that this was the right pattern to use for that kind of thing.  

The use case I have in mind is an editor for a complex page having several text fields/drop-downs that are persisted to various tables in a DB.  After the user clicks "save", I wanted all the changes to be saved (or fail to save, with error message) as a group.

Thanks


Thomas Broyer

unread,
Apr 4, 2011, 10:53:27 AM4/4/11
to google-we...@googlegroups.com


On Monday, April 4, 2011 3:41:59 PM UTC+2, KaffeineComa wrote:

Assuming "requestContext" above actually is a Request (not a RequestContext), that's abnormal.

If you're indeed talking about a RequestContext (and your T should be read as Void), then it's the normal behavior: the RequestContext-level Receiver's onFailure will only be called if the server (more or less) failed to deserialize the request or serialize the response. When processing service method invocations, each service method's Receiver's onFailure can be called, independently of the others, and the RequestContext-level Receiver's onSuccess will be called in the end.


Ah, well that's my problem then. In many cases I'm firing on the context rather than on the request, because I have stacked up multiple calls, and I want them to fire as a group, rather than having to fire them all serially. There was a posting in this group a while back (hah, good luck finding it!) suggesting that this was the right pattern to use for that kind of thing.  

The use case I have in mind is an editor for a complex page having several text fields/drop-downs that are persisted to various tables in a DB.  After the user clicks "save", I wanted all the changes to be saved (or fail to save, with error message) as a group.


You'd have to attach a Receiver to each call (using the .to() method of the Request) and handle failures there. A RequestContext is not synonymous to a transaction (it's more like a "batching" mechanism), so each service method call can fail independently of the others. You can very well wrap them all in a single transaction on the server side, but you can't communicate a "global failure" (actually, you could, with a ServiceLayerDecorator overriding invoke() to die() instead of report()ing an InvocationTargetException)
Reply all
Reply to author
Forward
0 new messages