Don't let (unexpected) exceptions slip by on timeouts
JAVA-268 #fixes
diff --git a/driver-core/src/main/java/com/datastax/driver/core/DefaultResultSetFuture.java b/driver-core/src/main/java/com/datastax/driver/core/DefaultResultSetFuture.java
index 7ab29b8..9dede88 100644
--- a/driver-core/src/main/java/com/datastax/driver/core/DefaultResultSetFuture.java
+++ b/driver-core/src/main/java/com/datastax/driver/core/DefaultResultSetFuture.java
@@ -221,4 +221,3 @@
}
}
}
-
diff --git a/driver-core/src/main/java/com/datastax/driver/core/PooledConnection.java b/driver-core/src/main/java/com/datastax/driver/core/PooledConnection.java
index 713857c..f4cc892 100644
--- a/driver-core/src/main/java/com/datastax/driver/core/PooledConnection.java
+++ b/driver-core/src/main/java/com/datastax/driver/core/PooledConnection.java
@@ -33,8 +33,7 @@
* Return the pooled connection to it's pool.
* The connection should generally not be reuse after that.
*/
- public void release()
- {
+ public void release() {
pool.returnConnection(this);
}
}
diff --git a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java
index 5c6c8c5..1a8ffba 100644
--- a/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java
+++ b/driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java
@@ -160,11 +160,15 @@
manager.executor().execute(new Runnable() {
@Override
public void run() {
- if (retryCurrent) {
- if (query(h))
- return;
+ try {
+ if (retryCurrent) {
+ if (query(h))
+ return;
+ }
+ sendRequest();
+ } catch (Exception e) {
+ setFinalException(null, new DriverInternalError("Unexpected exception while retrying query", e));
}
- sendRequest();
}
});
}
@@ -196,33 +200,40 @@
}
private void setFinalResult(Connection connection, Message.Response response) {
- if (timerContext != null)
- timerContext.stop();
+ try {
+ if (timerContext != null)
+ timerContext.stop();
- ExecutionInfo info = current.defaultExecutionInfo;
- if (triedHosts != null)
- {
- triedHosts.add(current);
- info = new ExecutionInfo(triedHosts);
+ ExecutionInfo info = current.defaultExecutionInfo;
+ if (triedHosts != null)
+ {
+ triedHosts.add(current);
+ info = new ExecutionInfo(triedHosts);
+ }
+ if (retryConsistencyLevel != null)
+ info = info.withAchievedConsistency(retryConsistencyLevel);
+ callback.onSet(connection, response, info, System.nanoTime() - startTime);
+ } catch (Exception e) {
+ callback.onException(connection, new DriverInternalError("Unexpected exception while setting final result from " + response, e), System.nanoTime() - startTime);
}
- if (retryConsistencyLevel != null)
- info = info.withAchievedConsistency(retryConsistencyLevel);
- callback.onSet(connection, response, info, System.nanoTime() - startTime);
}
private void setFinalException(Connection connection, Exception exception) {
- if (timerContext != null)
- timerContext.stop();
- callback.onException(connection, exception, System.nanoTime() - startTime);
+ try {
+ if (timerContext != null)
+ timerContext.stop();
+ } finally {
+ callback.onException(connection, exception, System.nanoTime() - startTime);
+ }
}
@Override
public void onSet(Connection connection, Message.Response response, long latency) {
- if (connection instanceof PooledConnection)
- ((PooledConnection)connection).release();
-
Host queriedHost = current;
try {
+ if (connection instanceof PooledConnection)
+ ((PooledConnection)connection).release();
+
switch (response.type) {
case RESULT:
setFinalResult(connection, response);
@@ -405,11 +416,12 @@
@Override
public void onException(Connection connection, Exception exception, long latency) {
- if (connection instanceof PooledConnection)
- ((PooledConnection)connection).release();
Host queriedHost = current;
try {
+ if (connection instanceof PooledConnection)
+ ((PooledConnection)connection).release();
+
if (exception instanceof ConnectionException) {
if (metricsEnabled())
metrics().getErrorMetrics().getConnectionErrors().inc();
@@ -420,6 +432,9 @@
}
setFinalException(connection, exception);
+ } catch (Exception e) {
+ // This shouldn't happen, but if it does, we want to signal the callback, not let him hang indefinitively
+ setFinalException(null, new DriverInternalError("An unexpected error happened while handling exception " + exception, e));
} finally {
if (queriedHost != null)
manager.cluster.manager.reportLatency(queriedHost, latency);
@@ -428,15 +443,20 @@
@Override
public void onTimeout(Connection connection, long latency) {
- if (connection instanceof PooledConnection)
- ((PooledConnection)connection).release();
-
Host queriedHost = current;
- logError(connection.address, "Timeout during read");
- retry(false, null);
+ try {
+ if (connection instanceof PooledConnection)
+ ((PooledConnection)connection).release();
- if (queriedHost != null)
- manager.cluster.manager.reportLatency(queriedHost, latency);
+ logError(connection.address, "Timeout during read");
+ retry(false, null);
+ } catch (Exception e) {
+ // This shouldn't happen, but if it does, we want to signal the callback, not let him hang indefinitively
+ setFinalException(null, new DriverInternalError("An unexpected error happened while handling timeout", e));
+ } finally {
+ if (queriedHost != null)
+ manager.cluster.manager.reportLatency(queriedHost, latency);
+ }
}
interface Callback extends Connection.ResponseCallback {