users@jersey.java.net

[Jersey] Re: 204 status returned instead of 500 when throwing WebApplicationException

From: sdoca sdoca <sdoca_at_shaw.ca>
Date: Wed, 01 Feb 2012 16:48:38 -0700

Hi,

It was my understanding that a method with a return type (i.e. not void) should return a 404 status when the return object is null.  Not sure why I had that idea in my head.

I created another method on the resource:

    @GET
    @Path("/exception")
    public String pingException()
    {
        throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
    }

and when the client calls that I catch a UniformInterfaceException with the expected 500 status.

    public String pingException()
    {
        try
        {
            return provisioningService.path("/exception").get(String.class);
        }
        catch (UniformInterfaceException ex)
        {
            return "Return code: " + ex.getResponse().getStatus();
        }
        catch (Throwable ex)
        {
            return "pingException caught unexpected throwable " + ex.getMessage();
        }
    }

Why the "real" method (querySubscriberAccount) throws a UniformInterfaceException with a 204 status is completey baffling!!!

----- Original Message -----
From: Petr Jurák <petr.jurak_at_gmail.com>
Date: Wednesday, February 1, 2012 2:30 pm
Subject: [Jersey] Re: 204 status returned instead of 500 when throwing WebApplicationException
To: users_at_jersey.java.net

> Hi,
>
> If you return null, then client have to expect 204 no content, because
> entity body is empty. It's from JAX-RS specification, chapter 3.3.3
> Return Type.
>
> But with that exception it is strange. Can you add a simple
> method (no
> params etc) a just throw an WebApplicationException whenever it is
> called?
>
> Br, Petr
>
>
> On 1 February 2012 22:10, sdoca sdoca <sdoca_at_shaw.ca> wrote:
> > Hi,
> >
> > I have written a couple other Jersey services and haven't had
> this issue
> > with them.  It's a bit of a mystery.
> >
> > I updated my resource class based on the workaround in the
> issue I linke to
> > in my OP.  It now looks like this:
> >
> >     @GET
> >     @Produces(MediaType.APPLICATION_XML)
> >     @Path("/subscriber")
> >     public SubscriberAccount querySubscriberAccount(
> >             @QueryParam("telephone") String telephone,
> >             @QueryParam("cmsFQDN") String cmsFQDN)
> >     {
> >         logger.debug("Entering querySubscriberAccount()
> {telephone}=[">                 + telephone + "] {cmsFQDN}=[" +
> cmsFQDN + "]");
> >
> >         assert (null != provisionService);
> >
> >         final SubscriberAccount account;
> >
> >         try
> >         {
> >             account =
> provisionService.querySubscriber(telephone, cmsFQDN);
> >
> >             if (account != null)
> >             {
> >                 logger.debug("The {provisionService} reports
> [" + account +
> > "]");
> >             }
> >             else
> >             {
> >                 logger.debug("No account was found");
> >             }
> >         }
> >         catch (IllegalArgumentException ex)
> >         {
> >             logger.error("Illegal argument while executing
> query for
> > subscriber account: ",
> >                     ex);
> >
> >             throw new
> WebApplicationException(Response.Status.BAD_REQUEST);>         }
> >         catch (Exception ex)
> >         {
> >             logger.error("Unexpected exception while executing
> query for
> > subscriber account",
> >                     ex);
> >
> >             throw new
> > WebApplicationException(Response.serverError().build());
> >
> >             // throw new
> >             //
> > WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
> >         }
> >
> >         logger.debug("Exiting querySubscriberAccount()");
> >
> >         return account;
> >     }
> >
> > The resource makes calls to another service which was throwing
> an exception
> > which was caught and the 500 error status returned. 
> Unfortunately, that
> > service has now been fixed and no longer throwing the
> exception.  So, now in
> > my service logs I'm seeing the log statement:
> >
> >     2012 Feb 01 13:30:52,818 MST [http-thread-pool-80(2)] DEBUG
> > ProvisionResource - No account was found
> >
> > BUT, the client is still receiving a 204 status.  The client
> call to the
> > resource looks like this:
> >
> >     public SubscriberAccount querySubscriberAccount(final
> String accountNum)
> >         throws ProvisioningException
> >     {
> >         SubscriberAccount subscriberAccount = null;
> >         WebResource querySubscriberResource = null;
> >
> >         try
> >         {
> >             querySubscriberResource =
> > provisioningService.path(PATH_SUBSCRIBER)
> >                     .queryParam(PARAM_KEY_ACCOUNT, accountNum);
> >
> >             subscriberAccount =
> > querySubscriberResource.accept(MediaType.APPLICATION_XML)
> >                     .get(SubscriberAccount.class);
> >
> >             logger.info("SubscriberAccount retrieved for
> account number: " +
> > accountNum + " - " + subscriberAccount);
> >         }
> >         catch (UniformInterfaceException ex)
> >         {
> >             final int status = ex.getResponse().getStatus();
> >
> >             if (404 == status)
> >             {
> >                 logger.info("No subscriber account provisioned
> for account
> > number: "
> >                         + accountNum + "at web resource: " +
> > querySubscriberResource);
> >             }
> >             else
> >             {
> >                 final String message = "Unexpected webservice
> response with
> > status code: "
> >                         + ex.getResponse().getStatus();
> >
> >                 logger.error(message, ex);
> >
> >                 throw new ProvisioningException(message);
> >             }
> >         }
> >         catch (Throwable ex)
> >         {
> >             logger.error("querySubscriberAccount caught unexpected
> > throwable",
> >                     ex);
> >
> >             throw new ProvisioningException(ex.getMessage());
> >         }
> >         finally
> >         {
> >             logger.debug("Exiting querySubscriberAccount - returning
> > {subscriberAccount}=["
> >                     + subscriberAccount + "]");
> >         }
> >
> >         return subscriberAccount;
> >     }
> >
> > Since the resource is returning null, I would expect the
> status returned to
> > be 404.  However, it is still a 204 as shown in the client logs:
> >
> > 2012 Feb 01 13:30:54,820 MST [Ejb-Async-Thread-4] ERROR
> ProvisioningClient -
> > Unexpected webservice response with status code: 204
> > com.sun.jersey.api.client.UniformInterfaceException: GET
> > http://app30/provisioning-
> service/provision/subscriber?accountNum=037005590> returned a
> response status of 204 No Content
> >         at
> >
> com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:528)>         at
> >
> com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:506)>
> > Not only was I expecting a 404 status, but I'm confused as to
> why a 204
> > response would cause a UniformInterfaceException.  According
> to the API
> > doing a get on a WebResource will throw a
> UniformInterfaceException "if the
> > status of the HTTP response is greater than or equal to 300
> and c is not the
> > type ClientResponse."
> >
> > Again, if anyone can help with these issues, it would be really
> > appreciated!!
> >
> > ----- Original Message -----
> > From: Petr Jurák <petr.jurak_at_gmail.com>
> > Date: Wednesday, February 1, 2012 1:04 pm
> > Subject: [Jersey] Re: 204 status returned instead of 500 when
> throwing> WebApplicationException
> > To: users_at_jersey.java.net
> >
> >> Hi,
> >>
> >> I have similar resource and Jersey 1.9.1 and exception
> handling is
> >> behaving well (I mean that the client gets 500 as expected).
> >> Could you
> >> please double check your stack trace?
> >> And what jee server are you using?
> >>
> >> Br, Petr
> >>
> >> On 1 February 2012 19:04,  <sdoca_at_shaw.ca> wrote:
> >> > I have a Jersey web service with the following a resource class:
> >> >
> >> >    @Stateless
> >> >    @Path("/provision")
> >> >    public class ProvisionResource
> >> >    {
> >> >        private final Logger logger =
> >> > LoggerFactory.getLogger(ProvisionResource.class);
> >> >
> >> >        @EJB
> >> >        private ProvisionService provisionService;
> >> >
> >> >        @GET
> >> >        @Produces(MediaType.APPLICATION_XML)
> >> >        @Path("/subscriber")
> >> >        public SubscriberAccount querySubscriberAccount(
> >> >                @QueryParam("accountNum") String accountNum)
> >> >        {
> >> >            logger.debug("Entering querySubscriberAccount()");
> >> >
> >> >            final SubscriberAccount account;
> >> >
> >> >            try
> >> >            {
> >> >                account =
> >> provisionService.querySubscriber(accountNum);>
> >> >                if (account != null)
> >> >                {
> >> >                    logger.debug("Retreived account = " +
> account);>> >                }
> >> >                else
> >> >                {
> >> >                    logger.debug("No account was found for " +
> >> > accountNum);
> >> >                }
> >> >            }
> >> >            catch (IllegalArgumentException ex)
> >> >            {
> >> >                logger.error("Illegal argument while
> executing query
> >> > for subscriber account",
> >> >                        ex);
> >> >
> >> >                throw new
> >> > WebApplicationException(Response.Status.BAD_REQUEST);
> >> >            }
> >> >            catch (Exception ex)
> >> >            {
> >> >                logger.error("Unexpected exception while executing
> >> > query for subscriber account",
> >> >                        ex);
> >> >
> >> >                throw new
> >> > WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
> >> >            }
> >> >
> >> >            logger.debug("Exiting querySubscriberAccount()");
> >> >
> >> >            return account;
> >> >        }
> >> >
> >> >    .... snip ....
> >> >
> >> >    }
> >> >
> >> > The `provisionService.querySubscriber` throws an exception
> >> which is
> >> > caught by the second catch statement in the
> `querySubscriberAccount`>> > method (we see the log statement in
> the file).  However, the
> >> client is
> >> > receiving a `204` status instead of the expected `500` error.
> >> >
> >> > I did find this issue which is similar to mine:
> >> > http://java.net/jira/browse/JERSEY-41 but is quite old and for
> >> Jersey> 1.3.1.  We are using version 1.9.1.
> >> >
> >> > Has anyone else seen this issue and hopefully figured out
> what the
> >> > problem is?
> >>
>