diff --git a/src/main/java/com/launchdarkly/eventsource/EventSource.java b/src/main/java/com/launchdarkly/eventsource/EventSource.java index 390c834..989e3c0 100644 --- a/src/main/java/com/launchdarkly/eventsource/EventSource.java +++ b/src/main/java/com/launchdarkly/eventsource/EventSource.java @@ -300,21 +300,22 @@ private void newConnectionAttempt(AtomicLong connectedTime) { if (response.isSuccessful()) { connectedTime.set(System.currentTimeMillis()); handleSuccessfulResponse(response); + + // If handleSuccessfulResponse returned without throwing an exception, it means the server + // ended the stream. We don't call the handler's onError() method in this case; but we will + // call the ConnectionErrorHandler with an EOFException, in case it wants to do something + // special in this scenario (like choose not to retry the connection). However, first we + // should check the state in case we've been deliberately closed from elsewhere. + ReadyState state = readyState.get(); + if (state != SHUTDOWN && state != CLOSED) { + logger.warn("Connection unexpectedly closed"); + errorHandlerAction = connectionErrorHandler.onConnectionError(new EOFException()); + } } else { logger.debug("Unsuccessful response: {}", response); errorHandlerAction = dispatchError(new UnsuccessfulResponseException(response.code())); } } - // If handleSuccessfulResponse returned without throwing an exception, it means the server - // ended the stream. We don't call the handler's onError() method in this case; but we will - // call the ConnectionErrorHandler with an EOFException, in case it wants to do something - // special in this scenario (like choose not to retry the connection). However, first we - // should check the state in case we've been deliberately closed from elsewhere. - ReadyState state = readyState.get(); - if (state != SHUTDOWN && state != CLOSED) { - logger.warn("Connection unexpectedly closed"); - errorHandlerAction = connectionErrorHandler.onConnectionError(new EOFException()); - } } catch (IOException e) { ReadyState state = readyState.get(); if (state != SHUTDOWN && state != CLOSED) { diff --git a/src/test/java/com/launchdarkly/eventsource/EventSourceHttpReconnectTest.java b/src/test/java/com/launchdarkly/eventsource/EventSourceHttpReconnectTest.java index f9a538c..e9ffe30 100644 --- a/src/test/java/com/launchdarkly/eventsource/EventSourceHttpReconnectTest.java +++ b/src/test/java/com/launchdarkly/eventsource/EventSourceHttpReconnectTest.java @@ -21,6 +21,7 @@ import static com.launchdarkly.eventsource.StubServer.Handlers.stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; /** * End-to-end tests with real HTTP, specifically for the client's reconnect behavior. @@ -211,6 +212,10 @@ public Action onConnectionError(Throwable t) { // Therefore we don't expect to see any items in eventSink. eventSink.assertNoMoreLogItems(); + assertNotNull(server.awaitRequest(Duration.ZERO)); + assertNull(server.awaitRequest(Duration.ZERO)); // no more requests should have been made + assertEquals(0, receivedError.size()); // error handler should have only been called once + assertEquals(ReadyState.SHUTDOWN, es.getState()); } }