diff --git a/driver-core/src/main/com/mongodb/MongoTimeoutException.java b/driver-core/src/main/com/mongodb/MongoTimeoutException.java index e2cce02403a..ded287ea516 100644 --- a/driver-core/src/main/com/mongodb/MongoTimeoutException.java +++ b/driver-core/src/main/com/mongodb/MongoTimeoutException.java @@ -18,6 +18,7 @@ import com.mongodb.annotations.Alpha; import com.mongodb.annotations.Reason; +import com.mongodb.lang.Nullable; /** * An exception indicating that the driver has timed out waiting for either a server or a connection to become available. @@ -42,7 +43,7 @@ public MongoTimeoutException(final String message) { * @since 5.2 */ @Alpha(Reason.CLIENT) - public MongoTimeoutException(final String message, final Throwable cause) { + public MongoTimeoutException(final String message, @Nullable final Throwable cause) { super(message, cause); } } diff --git a/driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java b/driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java index 0ef94d559c9..013effea263 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultConnectionPool.java @@ -345,7 +345,7 @@ private PooledConnection getPooledConnection(final Timeout waitQueueTimeout, fin } return new PooledConnection(internalConnection); } catch (MongoTimeoutException e) { - throw createTimeoutException(startTime); + throw createTimeoutException(startTime, e); } } @@ -359,13 +359,14 @@ private PooledConnection getPooledConnectionImmediate() { return internalConnection == null ? null : new PooledConnection(internalConnection); } - private MongoTimeoutException createTimeoutException(final StartTime startTime) { + private MongoTimeoutException createTimeoutException(final StartTime startTime, @Nullable final MongoTimeoutException cause) { long elapsedMs = startTime.elapsed().toMillis(); int numPinnedToCursor = pinnedStatsManager.getNumPinnedToCursor(); int numPinnedToTransaction = pinnedStatsManager.getNumPinnedToTransaction(); if (numPinnedToCursor == 0 && numPinnedToTransaction == 0) { return new MongoTimeoutException(format("Timed out after %d ms while waiting for a connection to server %s.", - elapsedMs, serverId.getAddress())); + elapsedMs, serverId.getAddress()), + cause); } else { int maxSize = pool.getMaxSize(); int numInUse = pool.getInUseCount(); @@ -375,7 +376,7 @@ private MongoTimeoutException createTimeoutException(final StartTime startTime) * - numInUse > 0 * we consider at least one of `numPinnedToCursor`, `numPinnedToTransaction` to be positive, * so if we observe `numInUse` to be 0, we have to estimate it based on `numPinnedToCursor` and `numPinnedToTransaction`; - * - numInUse < maxSize + * - numInUse <= maxSize * `numInUse` must not exceed the limit in situations when we estimate `numInUse`; * - numPinnedToCursor + numPinnedToTransaction <= numInUse * otherwise the numbers do not make sense. @@ -399,7 +400,8 @@ private MongoTimeoutException createTimeoutException(final StartTime startTime) + "connections in use by other operations: %d", elapsedMs, serverId.getAddress(), sizeToString(maxSize), numPinnedToCursor, numPinnedToTransaction, - numOtherInUse)); + numOtherInUse), + cause); } } @@ -1067,7 +1069,7 @@ private PooledConnection acquirePermitOrGetAvailableOpenedConnection(final boole & (availableConnection = tryGetAvailable ? tryGetAvailableConnection() : null) == null) { Timeout.onExistsAndExpired(waitQueueTimeout, () -> { - throw createTimeoutException(startTime); + throw createTimeoutException(startTime, null); }); waitQueueTimeout.awaitOn(permitAvailableOrHandedOverOrClosedOrPausedCondition, () -> "acquiring permit or getting available opened connection"); @@ -1406,7 +1408,7 @@ void failAsClosed() { } void failAsTimedOut() { - doComplete(() -> createTimeoutException(startTime)); + doComplete(() -> createTimeoutException(startTime, null)); } private void doComplete(final Supplier failureSupplier) {