Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

204 Status triggers UniformInterfaceException on the client side #1334

Closed
jerseyrobot opened this issue Apr 2, 2012 · 11 comments
Closed

204 Status triggers UniformInterfaceException on the client side #1334

jerseyrobot opened this issue Apr 2, 2012 · 11 comments

Comments

@jerseyrobot
Copy link
Contributor

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 GlassFish Server Open Source Edition 3.1.1 (build 12) with Jersey 1.8-1.10.

Environment

Linux 2.6.18-274.12.1.el5 #1 SMP Tue Nov 29 13:37:46 EST 2011 x86_64 x86_64 x86_64 GNU/Linux

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
Reported by sdoca

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
mmatula said:
It will be hard for us to debug this without a reproducible test case. We need a little help from you. Can you try removing everything from the method and just throw a new WebApplicationException()? Does that return the right status code, or is it still returning 204? Do you have any exception mappers on your classpath? How do they look like?
Can you add a snippet of your log file showing it does log the exception but returns 204? Can you try throwing a generic runtime exception instead of WebApplicationException to see what it does?

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
sdoca said:
Hi,

I had already created a method that throws a WebApplicationException for testing which works as expected (the client receives a 500 status):

**pingException**    @GET
    @Path("/exception")
    public String pingException()
    {
        logger.info("pingException called");

        throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
    }

My client code that calls the querySubscriber resource method on the server looks like this:

**querySubscriberAccount**    public SubscriberAccount querySubscriberAccount(final String subscriberNum) throws Exception
    {
        logger.debug("Entering querySubscriberAccount {subscriberNum}=[" + subscriberNum+ "]");

        SubscriberAccount subscriberAccount = null;

        try
        {
            Builder querySubscriberBuilder = provisioningService.path(PATH_SUBSCRIBER)
    .queryParam(PARAM_KEY_SUBSCRIBER_NUM, subscriberNum)
    .accept(MediaType.APPLICATION_XML);

            subscriberAccount = querySubscriberBuilder.get(SubscriberAccount.class);

            logger.info("SubscriberAccount retrieved: " + subscriberAccount);
        }
        catch (UniformInterfaceException ex)
        {
            final int status = ex.getResponse().getStatus();

            // This a hack! A 204 status should NOT be returned in a
            // UniformInterfaceException, but for some as yet unknown reason,
            // the service does.
            if (status == 204)
            {
logger.debug("Caught unexpected UniformInterfaceException with status code: " + status);

logger.info("No subscriber account provisioned");
            }
            else
            {
final String message = "Unexpected webservice response querying subscriber account with status code: "
        + ex.getResponse().getStatus();

logger.error(message, ex);

throw new Exception(message);
            }
        }
        catch (Throwable ex)
        {
            logger.error("querySubscriberAccount caught unexpected throwable",
    ex);
            throw new Exception(ex.getMessage());
        }

        return subscriberAccount;
    }

These are the logs from that method showing that I get the status when I catch the UniformInterfaceException is 204:

2012 Apr 13 13:46:31,680 MDT [pool-52-thread-1] DEBUG my.package.MyClient - Entering querySubscriberAccount

{subscriberNum}

=[9999999999]
2012 Apr 13 13:46:43,948 MDT [pool-52-thread-1] DEBUG my.package.MyClient - Caught unexpected UniformInterfaceException with status code: 204
2012 Apr 13 13:46:43,948 MDT [pool-52-thread-1] INFO my.package.MyClient - No subscriber account provisioned
2012 Apr 13 13:46:43,948 MDT [pool-52-thread-1] DEBUG my.package.MyClient - Exiting querySubscriberAccount

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
mmatula said:
OK, thanks for the additional info. What leads you to think the code on the server actually throws the WebApplicationException instead of just returning null from querySubscriberAccount() which would correctly lead to 204?

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
sdoca said:
I don't think the server is throwing a WebApplicationException; I think it's throwing a UniformInterfaceException with a 204 status when it should just be returning a 204 status.

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
mmatula said:
Ah, I see what you mean. So you are saying in case of 204 the querySubscriberBuilder.get(SubscriberAccount.class) method call should simply return null instead of throwing UniformInterfaceException, right? Makes sense.

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
mmatula said:
Updated the issue summary to match the actual issue.

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
@pavelbucek said:
there is a test in jersey-tests (class NoContentResponseTest) which tests exactly this behavior - that UniformInterfaceException is thrown. I can see your point, but jersey client is not able to produce some kind of "default" or "empty" answer in case 204 is returned, so it somehow makes sense to throw it (you want SubscriberAccount instance and you are not getting it).

see http://java.net/jira/browse/JERSEY-167 (patch for this issue introduced described functionality).

If you expect statuses other than 200, you should modify your code to receive ClientResponse class, check for response status and (if relevant) for its entity.

Closing as won't fix.

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
Marked as won't fix on Wednesday, May 2nd 2012, 4:22:24 am

@jerseyrobot
Copy link
Contributor Author

@glassfishrobot Commented
This issue was imported from java.net JIRA JERSEY-1062

@jerseyrobot
Copy link
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant