users@jax-rs-spec.java.net

[jax-rs-spec users] [jsr339-experts] Re: AsyncResponse unmapped exception and CompletionCallback

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 8 Feb 2013 21:50:56 +0000

Good Evening Bill,
On 08/02/13 21:39, Bill Burke wrote:
>
>
> On 2/8/2013 4:18 PM, Sergey Beryozkin wrote:
>> On 08/02/13 14:18, Sergey Beryozkin wrote:
>>> Hi,
>>> I've been experimenting with throwing unmapped exceptions via
>>> AsyncResponse.resume(Throwable); and expecting to see a registered
>>> CompletionCallback.onComplete(Throwable) be invoked in such cases, with
>>> the runtime making sure the underlying javax.servler.AsyncListener
>>> onComplete and onError callbacks delegating to
>>> CompletionCallback.onComplete(Throwable).
>>>
>>> What I'm seeing is that CompletionCallback.onComplete(Throwable) is
>>> indeed called in case of unmapped exceptions, but via
>>> AsyncListener.onComplete path, and thus,
>>> CompletionCallback.onComplete(Throwable) having a null Throwable.
>>>
>>> What I'm not sure if it is the JAX-RS implementation problem or that of
>>> the underlying javax.servlet.AsyncContext's implementation ?
>>>
>>> In other words, how to get it call back AsyncListener.onError() ?
>>
>> OK, I'm thinking I've got it. It is the responsibility of the JAX-RS
>> runtime to ensure that the unmapped exception can be made visible to
>> CompletionCallback,
>> Marek - if it is not the case please correct me, but I think this is how
>> it should work,
>>
>> Now, back to that updated AsyncResponse.resume() Javadocs update:
>> "except that unmapped exceptions are not re-thrown by JAX-RS runtime to
>> be handled by a hosting I/O container. Instead, any unmapped exceptions
>> are propagated to the hosting I/O container via a container-specific
>> callback mechanism. Depending on the container implementation,
>> propagated unmapped exceptions typically result in an error status
>> being sent to the client and/or the connection being closed."
>>
>> FYI, rethrowing it works with Jetty - but not with Tomcat.
>>
>> Either way, why can't we simply say that "unmapped exceptions will
>> result in 500 status being sent to the client" and thus make it up to
>> the given JAX-RS implementation to ensure it is the case ?
>>
>
> I don't think you need to worry about Servlet 3.0 callbacks. This is the
> way we implement resume(Object)
>
> try {
> - Create a 200 Response with the resume() parameter if it is not a
> Response already
> - Set the content-type based on Accept parameters and original JAX-RS
> method
> - filter the response
> - Call WriterInterceptor/MBW chain
> } catch (Throwable ex) {
> return resume(ex);
> }
>
> - Servlet 3.0 asyncContext.complete();
> - invoke callbacks (null)
>
> The resume(Throwable) looks like this:
>
> try {
> if (mappable(throwable)) map;
> else sendError(500);
> } catch (Throwable ignore) {
> log exception
> }
> finally {
> servlet3 asyncContext.complete();
> }
>
> invoke completion callbacks(throwable);
>
>
Thanks for the tip, I think I've done now the unmapped case exactly the
way you've suggested; which I guess further supports the idea of the
simplification of resume javadocs ? (re 500 in case of unmapped), guess
this is not that important but can make it more specific.

Cheers, Sergey