dev@jsr311.java.net

Re: JSR311: Exception Handling

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 01 Apr 2008 11:55:53 +0200

Stephan Koops wrote:
> Hi all,
>
> IMO all not specially handled Exceptions (checked and RuntimeExc) should
> result in status 500. The ExceptionMapper is useful, to allow special
> handling for special exception classes. IMO the runtime environment
> should warn, if it found resource methods with declared exceptions
> (RuntimeExc AND non-runtime exceptions, excluding
> WebApplicationException), for which no corresponding ExceptionMapper is
> available. But if folks don't want this, every container could do this
> for its own.
>

Yes, that is the idea let the container handle exceptions if not handled
by the JAX-RS runtime.


> I do not see any advantage of the ContainerException. The runtime
> environment could also handle exceptions directly. Let me know, what I
> am missing.
>

It is a standard way to wrap a checked exception and for it to be passed
to the container, for example, consider this hypothetical example:

   @GET
   public byte[] get(@Param("charset") String charset)
           throws java.io.UnsupportedEncodingException {
       return "CONTENT".getBytes(charset);
   }

how would the checked exception UnsupportedEncodingException be
propagated and caught by the runtime and rethrown by the runtime to pass
it to the container (if no exception provider is found for
UnsupportedEncodingException) ?

i.e. there is always an escape hatch to the container.


> IOExceptions should not especially allowed, IMO: IOExc are allowed in
> Servlets (e.g.), because they could occur while writing to the network
> OutputStream, and there is no usefull handling possible. By contrast
> JAX-RS resource methods have no access to the OutputStream, so
> IOExceptions could not be thrown from this OutputStream. (The
> StreamingOutput allows throwing IOExc, but this is outside of the
> resource method.) All other IOExceptions (resulting from reading data
> for the resource) should be converted to (or wrapped into) to a
> reasonable, meaningful WebApplicationException IMO. (responsibility of
> app develpers)

The servlet spec does not explicitly specify that IOExceptions should
only be thrown due to reading/writing from the servlet input/output
streams (it is all a bit vague!). IOExceptions could be thrown by
reading/writing other information in preparation for consuming or
producing a representation. As you say such exceptions should really be
caught by I am not sure we can do much about it to enforce such a rule.


> IMO it is also not useful to allow ServletExceptions. It creates a
> dependency to Servlets, and I see no advantage for this. Where is it
> useful, to throw an ServletException, without wrapping Exceptions in a
> Servlet method? Let me know.
>

The processing of wrapped IOException and ServletException are specific
only to the JAX-RS servlet container.

If the Servlet container catches the runtime ContainerException and the
wrapped exception is either IOException or ServletException then it
re-throws the wrapped exception otherwise it re-throws the
ContainerException.

The thinking behind this was that developers may want to transition some
servlet code to JAX-RS code but still may need to call other "legacy"
functionality (that throws IOException and/or ServletException) and they
want to retain the same behavior when exceptions are thrown.

Paul.

> best regards
> Stephan
>
> Marc Hadley schrieb:
>> Issue 26[1] concerns exception handling. Currently the only exception
>> handled by a JAX-RS runtime is our own WebApplicationException, any
>> RuntimeException is propagated to the container, and we don't say what
>> should happen if a resource method declares checked exceptions (see
>> ednote 3.1 in the latest spec draft). Here's a proposal for addressing
>> this:
>>
>> (i) Allow resource methods to declare checked exceptions
>>
>> (ii) Define a new provider type along the following lines:
>>
>> public interface ExceptionMapper<E extends Exception> {
>>
>> boolean isMappable(Class<E> type); // not sure if we really need this
>>
>> Response map(E exception);
>> }
>>
>> An application can define implementations of this interface to convert
>> any runtime or checked exception to a Response that will then be
>> processed in the usual way. Implementations will catch all exceptions
>> and look for a provider that will handle the exception. If one is
>> found it is used to create a response, if not the implementation
>> rethrows the exception, see (iv).
>>
>> (iii) Define provider ordering such that the closest matching
>> exception mapper (by inheritance hierarchy) is used. Thus if an
>> application provides ExceptionMapper<Exception> and
>> ExceptionMapper<RuntimeException> and the application throws
>> IndexOutOfBoundsException then the implementation of
>> ExceptionMapper<RuntimeException> will be used.
>>
>> (iv) Define a new RuntimeException: ContainerException. An application
>> can throw this exception directly to have the exception propagate to
>> the container. An implementation will use this to wrap checked
>> exceptions thrown by a resource method and not handled by an exception
>> mapper provider. Runtime exceptions not handled by an exception mapper
>> provider will be rethrown directly.
>>
>> (v) Define deviations to (iv) for servlet container. An servlet-based
>> implementation won't wrap ServletException or IOException since these
>> can be thrown directly.
>>
>> Thoughts, comments ?
>> Marc.
>>
>> [1] https://jsr311.dev.java.net/issues/show_bug.cgi?id=26
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109