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 14:10:37 -0700

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?
>