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

Jersey Client - Response status code ignored if server closes connection #4003

Closed
sumitkdey opened this issue Dec 5, 2018 · 8 comments
Closed
Assignees
Labels
enhancement New feature or request

Comments

@sumitkdey
Copy link

Hello,

If during a PUT call, the web server responds with the error status code and closes the connection (before the client finishes streaming all the data), jersey client raises an IOException and ignores the status code returned by the server.

Caused by: javax.ws.rs.ProcessingException: java.io.IOException: Error writing request body to server
	at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
	at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
	at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.put(JerseyInvocation.java:326)
	at com.oracle.bmc.http.internal.ForwardingInvocationBuilder.put(ForwardingInvocationBuilder.java:134)
	at com.oracle.bmc.http.internal.RestClient.put(RestClient.java:351)
	... 7 more
Caused by: java.io.IOException: Error writing request body to server
	at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.checkError(HttpURLConnection.java:3518)
	at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3501)
	at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:229)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:299)
	at org.glassfish.jersey.message.internal.ReaderWriter.writeTo(ReaderWriter.java:116)
	at org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider.writeTo(AbstractMessageReaderWriterProvider.java:79)
	at org.glassfish.jersey.message.internal.InputStreamProvider.writeTo(InputStreamProvider.java:105)
	at org.glassfish.jersey.message.internal.InputStreamProvider.writeTo(InputStreamProvider.java:60)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
	at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:517)
	at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:499)
	at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:393)
	at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
	... 19 more

Going through the code, it seems that the IOException is raised from line 360 before the response status code is read in line 366.

});
request.writeEntity();
} else {
setOutboundHeaders(request.getStringHeaders(), uc);
}
final int code = uc.getResponseCode();
final String reasonPhrase = uc.getResponseMessage();
final Response.StatusType status =
reasonPhrase == null ? Statuses.from(code) : Statuses.from(code, reasonPhrase);

In case the response status code is available, returning that would be more valuable to the caller than the IOException in this case.

@jansupol jansupol added the enhancement New feature or request label Dec 7, 2018
@jansupol
Copy link
Contributor

jansupol commented Dec 7, 2018

Sounds like we could do something about it. A reproducer would help us.

@sumitkdey
Copy link
Author

Thanks @jansupol Here is a test that runs into this issue - https://gist.github.com/sumitkdey/7cff1bb70d9d9a5dc2570b2f7146d2e2/2d1fdfa6e382324e5e1c4ff27b63406e53517749. Currently the test fails with an IOException error. It would be useful for the caller if instead of the exception, the failure status code could be returned in the response.

@jodoglevy
Copy link

@jansupol any updates on this issue?

@fzakaria
Copy link

fzakaria commented Oct 8, 2019

This would be a great fix.
I've also noticed that if a response for an "Expect: 100 Continue" is not 100 -- the HttpUrlConnection class raising an exception before storing the real status code (i.e. 412).

This status code is lost in Jersey where it simply raises a ProcessingException(-1) instead.

@jansupol jansupol self-assigned this Oct 9, 2019
@pankajtalk
Copy link

Hi @jansupol - is there any update on this issue? I am hitting it and a fix would be great. Thanks.

@pankajtalk
Copy link

Hi @jansupol - could you please let us know when this may be fixed? Also, if there is a workaround in the short time frame. Thanks.

@jansupol
Copy link
Contributor

jansupol commented May 7, 2020

The exception thrown is an exception and I do not think we can consume it and return the response instead, we need to let the user know that the exception has been thrown. What we can do, we can throw ResponseProcessingException with the response.

@jansupol
Copy link
Contributor

jansupol commented May 7, 2020

@sumitkdey Thanks for the reproducer, really helped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants