Open
Description
Using the HttpAdapter, when making a client call to a server that is unreachable an asynchronous callback is never triggered. The error is logged, but the callback is not called.
I tracked this down to org.restlet.engine.adapter.ClientAdapter.commit, specifically lines 90-108:
// Send the request to the client
httpCall.sendRequest(request, response, new Uniform() {
public void handle(Request request, Response response) {
try {
updateResponse(response,
new Status(httpCall.getStatusCode(), null,
httpCall.getReasonPhrase(), null),
httpCall);
if (userCallback != null) {
userCallback.handle(request, response);
}
} catch (Throwable t) {
getLogger()
.log(Level.WARNING,
"Unexpected error or exception inside the user call back",
t);
}
}
});
The exception shown below is thrown when httpCall.getStatusCode() is called, the catch block logs the error, but the callback is not called, so our application hangs.
Unexpected error or exception inside the user call back
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:378)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:473)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:203)
at sun.net.www.http.HttpClient.New(HttpClient.java:290)
at sun.net.www.http.HttpClient.New(HttpClient.java:306)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:995)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:931)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:849)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1090)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1253)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at org.restlet.ext.net.internal.HttpUrlConnectionCall.getStatusCode(HttpUrlConnectionCall.java:296)
at org.restlet.engine.adapter.ClientAdapter$1.handle(ClientAdapter.java:93)
at org.restlet.ext.net.internal.HttpUrlConnectionCall.sendRequest(HttpUrlConnectionCall.java:416)
at org.restlet.engine.adapter.ClientAdapter.commit(ClientAdapter.java:90)
at org.restlet.engine.adapter.HttpClientHelper.handle(HttpClientHelper.java:112)
at org.restlet.Client.handle(Client.java:180)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.resource.ClientResource.handle(ClientResource.java:1136)
at org.restlet.resource.ClientResource.handleOutbound(ClientResource.java:1225)
at org.restlet.resource.ClientResource.handle(ClientResource.java:1068)
at org.restlet.resource.ClientResource.handle(ClientResource.java:1044)
at org.restlet.resource.ClientResource.post(ClientResource.java:1453)
I was expecting that in this case the callback would be triggered with an error status. Our callback is set using setOnResponse:
ClientResource res = ...;
res.setOnResponse(new Uniform()
{
@Override
public void handle(Request request, Response response) {
// Not triggered if host is not reachable.
});