This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 1c2d920609d46e150a3ecb884ce7f1a6848baf09
Author: opencode <[email protected]>
AuthorDate: Mon Nov 2 21:46:49 2026 +0100

    Document both manifestations of pool exhaustion and the state it carries
    
    The class javadoc described only the synchronous manifestation: it now
    also states that the asynchronous borrow absorbs this exception into a
    wait, so exhaustion there surfaces through the Future as a
    TimeoutException for a timed wait, a CancellationException when the
    pool closes under the waiter, or an ExecutionException carrying the
    underlying failure - never as this exception. A reader who codes
    catch (PoolExhaustedException) around an async borrow now learns from
    the class itself why it catches nothing.
    
    The SQL_STATE constant's javadoc is corrected on two points found in a
    fresh review of the class. First, HY000 is shared with unrelated
    driver-reported general errors, so the state is a label to sort on, not
    an exclusive marker: a state-based classifier should corroborate with
    instanceof PoolExhaustedException. Second, the stamping is
    constructor-scoped by necessity and is now stated as such: the
    message-only constructor the pool throws through stamps the state, the
    constructors mirroring the SQLException signatures that take no state
    carry none, and an explicitly given state always wins.
    
    Normalize the mirrored constructors' SQL state parameter name from
    SQLState to sqlState, which the latter half of the constructor set
    already used.
---
 .../tomcat/jdbc/pool/PoolExhaustedException.java   | 29 ++++++++++++++++------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
index d47223e468..0dc4973a60 100644
--- 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
+++ 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PoolExhaustedException.java
@@ -19,7 +19,13 @@ package org.apache.tomcat.jdbc.pool;
 import java.sql.SQLException;
 
 /**
- * Exception thrown when the connection pool is exhausted and no connections 
are available.
+ * Exception thrown when the connection pool is exhausted and no connections 
are available. The caller of a synchronous
+ * borrow that is refused - one whose wait on the empty pool timed out - 
receives it directly. On the asynchronous path
+ * of {@link ConnectionPool#getConnectionAsync()} the same exhaustion is 
absorbed into a wait instead and never surfaces
+ * as this exception: an exhausted pool surfaces there through the {@link 
java.util.concurrent.Future} as a
+ * {@link java.util.concurrent.TimeoutException} for a timed wait, a {@link 
java.util.concurrent.CancellationException}
+ * when the pool closes under the waiter, or an {@link 
java.util.concurrent.ExecutionException} carrying the underlying
+ * failure when the wait could not be completed.
  */
 public class PoolExhaustedException extends SQLException {
 
@@ -31,7 +37,14 @@ public class PoolExhaustedException extends SQLException {
      * error, so none of the connection-class states (the {@code 08xxx} 
family, which
      * describe the session itself failing) says exactly this; still, 
consumers that
      * multiplex many {@link SQLException} sources and classify them by state 
need a
-     * non-null label to recognize pool exhaustion without referencing pool 
classes.
+     * non-null label to sort on. HY000 is shared with unrelated 
driver-reported
+     * general errors, so a state-based classifier should treat the state as a
+     * pointer and corroborate it with {@code instanceof 
PoolExhaustedException}
+     * rather than treat it as exclusive to pool exhaustion. The state is 
stamped by
+     * the message-only constructor the pool throws through; the constructors 
that
+     * mirror the {@code SQLException} signatures without a state parameter 
(no-arg
+     * and cause-only) carry none, as those super-signatures take none, and an
+     * explicitly given state always wins.
      */
     public static final String SQL_STATE = "HY000";
 
@@ -64,10 +77,10 @@ public class PoolExhaustedException extends SQLException {
      * Constructs a PoolExhaustedException with the specified detail message 
and SQL state.
      *
      * @param reason   the detail message
-     * @param SQLState the SQL state code
+     * @param sqlState the SQL state code
      */
-    public PoolExhaustedException(String reason, String SQLState) {
-        super(reason, SQLState);
+    public PoolExhaustedException(String reason, String sqlState) {
+        super(reason, sqlState);
     }
 
     /**
@@ -84,11 +97,11 @@ public class PoolExhaustedException extends SQLException {
      * Constructs a PoolExhaustedException with the specified detail message, 
SQL state, and vendor code.
      *
      * @param reason     the detail message
-     * @param SQLState   the SQL state code
+     * @param sqlState   the SQL state code
      * @param vendorCode the vendor-specific error code
      */
-    public PoolExhaustedException(String reason, String SQLState, int 
vendorCode) {
-        super(reason, SQLState, vendorCode);
+    public PoolExhaustedException(String reason, String sqlState, int 
vendorCode) {
+        super(reason, sqlState, vendorCode);
     }
 
     /**


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to