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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2953661adc Unwrap InvocationTargetException from underlying statement 
execution
2953661adc is described below

commit 2953661adcc871fe319b9ffbaf65655b8ff50ae4
Author: Michael Clarke <mcla...@apache.org>
AuthorDate: Thu Aug 8 20:26:58 2024 +0100

    Unwrap InvocationTargetException from underlying statement execution
    
    When executing a wrapped statement, any resulting SQLException is
    wrapped in an InvocationTargetException by the reflective invocation,
    which is rethrown by the InvocationHandler as an
    UndeclaredThrowableException. To ensure the expected SQLException is
    thrown, the invocation of the wrapped object is being moved into the
    existing try-catch block, thereby ensuring the InvocationTargetException
    is unwrapped and the underlying exception thrown by the handler.
---
 .../apache/tomcat/jdbc/pool/StatementFacade.java   | 22 ++++++++--------
 .../tomcat/jdbc/test/ProxiedStatementTest.java     | 30 ++++++++++++++++++++++
 .../apache/tomcat/jdbc/test/driver/Connection.java |  2 +-
 .../apache/tomcat/jdbc/test/driver/Statement.java  | 22 +++++++++++++++-
 4 files changed, 63 insertions(+), 13 deletions(-)

diff --git 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java
 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java
index e9cae3a734..600ff80d82 100644
--- 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java
+++ 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/StatementFacade.java
@@ -117,21 +117,21 @@ public class StatementFacade extends 
AbstractCreateStatementInterceptor {
                 throw new SQLException("Statement closed.");
             }
 
-            if (compare(GET_RESULTSET, method)) {
-                return getConstructor(RESULTSET_IDX, ResultSet.class)
+            Object result;
+            try {
+                if (compare(GET_RESULTSET, method)) {
+                    return getConstructor(RESULTSET_IDX, ResultSet.class)
                         .newInstance(new 
ResultSetProxy(method.invoke(delegate, args), proxy));
-            }
-            if (compare(GET_GENERATED_KEYS, method)) {
-                return getConstructor(RESULTSET_IDX, ResultSet.class)
+                }
+                if (compare(GET_GENERATED_KEYS, method)) {
+                    return getConstructor(RESULTSET_IDX, ResultSet.class)
                         .newInstance(new 
ResultSetProxy(method.invoke(delegate, args), proxy));
-            }
-            if (compare(EXECUTE_QUERY, method)) {
-                return getConstructor(RESULTSET_IDX, ResultSet.class)
+                }
+                if (compare(EXECUTE_QUERY, method)) {
+                    return getConstructor(RESULTSET_IDX, ResultSet.class)
                         .newInstance(new 
ResultSetProxy(method.invoke(delegate, args), proxy));
-            }
+                }
 
-            Object result = null;
-            try {
                 // invoke next
                 result = method.invoke(delegate, args);
             } catch (Throwable t) {
diff --git 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java
 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java
index 2c76115c06..0f07663b0e 100644
--- 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java
+++ 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/ProxiedStatementTest.java
@@ -58,4 +58,34 @@ public class ProxiedStatementTest extends DefaultTestCase {
             Assert.assertNotEquals(statement, new 
org.apache.tomcat.jdbc.test.driver.Statement());
         }
     }
+
+    @Test
+    public void shouldUnwrapInvocationTargetExceptionFromGetResultSet() throws 
SQLException {
+        this.datasource.setDriverClassName(Driver.class.getName());
+        this.datasource.setUrl("jdbc:tomcat:test");
+        try (Connection con = this.datasource.getConnection();
+             Statement statement = con.prepareStatement("sql", 
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, 
ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
+            Assert.assertThrows("Throwing exception on execute", 
SQLException.class, statement::getResultSet);
+        }
+    }
+
+    @Test
+    public void shouldUnwrapInvocationTargetExceptionFromExecute() throws 
SQLException {
+        this.datasource.setDriverClassName(Driver.class.getName());
+        this.datasource.setUrl("jdbc:tomcat:test");
+        try (Connection con = this.datasource.getConnection();
+             Statement statement = con.prepareStatement("sql", 
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, 
ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
+            Assert.assertThrows("Throwing exception on execute", 
SQLException.class, () -> statement.executeQuery(""));
+        }
+    }
+
+    @Test
+    public void shouldUnwrapInvocationTargetExceptionFromGetGeneratedKeys() 
throws SQLException {
+        this.datasource.setDriverClassName(Driver.class.getName());
+        this.datasource.setUrl("jdbc:tomcat:test");
+        try (Connection con = this.datasource.getConnection();
+             Statement statement = con.prepareStatement("sql", 
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, 
ResultSet.HOLD_CURSORS_OVER_COMMIT)) {
+            Assert.assertThrows("Throwing exception on execute", 
SQLException.class, statement::getGeneratedKeys);
+        }
+    }
 }
diff --git 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java
 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java
index 2c614e74a1..55ca60acff 100644
--- 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java
+++ 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Connection.java
@@ -218,7 +218,7 @@ public class Connection implements java.sql.Connection {
 
     @Override
     public PreparedStatement prepareStatement(String sql, int resultSetType, 
int resultSetConcurrency, int resultSetHoldability) throws SQLException {
-        return new org.apache.tomcat.jdbc.test.driver.Statement();
+        return new org.apache.tomcat.jdbc.test.driver.Statement(true);
     }
 
     @Override
diff --git 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
index d5a8e8ead6..16572487cb 100644
--- 
a/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
+++ 
b/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/driver/Statement.java
@@ -41,7 +41,18 @@ import java.util.Calendar;
 import java.util.Map;
 
 public class Statement implements CallableStatement {
-    int timeout=-1;
+
+    private boolean throwExceptionOnExecute = false;
+    private int timeout=-1;
+
+    public Statement() {
+        this(false);
+    }
+
+    public Statement(boolean throwExceptionOnExecute) {
+        this.throwExceptionOnExecute = throwExceptionOnExecute;
+    }
+
     @Override
     public Array getArray(int parameterIndex) throws SQLException {
         // TODO Auto-generated method stub
@@ -1099,6 +1110,9 @@ public class Statement implements CallableStatement {
 
     @Override
     public ResultSet executeQuery(String sql) throws SQLException {
+        if (throwExceptionOnExecute) {
+            throw new SQLException("Throwing exception on execute");
+        }
         return new org.apache.tomcat.jdbc.test.driver.ResultSet(this);
     }
 
@@ -1146,6 +1160,9 @@ public class Statement implements CallableStatement {
 
     @Override
     public ResultSet getGeneratedKeys() throws SQLException {
+        if (throwExceptionOnExecute) {
+            throw new SQLException("Throwing exception on execute");
+        }
         return new org.apache.tomcat.jdbc.test.driver.ResultSet(this);
     }
 
@@ -1180,6 +1197,9 @@ public class Statement implements CallableStatement {
 
     @Override
     public ResultSet getResultSet() throws SQLException {
+        if (throwExceptionOnExecute) {
+            throw new SQLException("Throwing exception on execute");
+        }
         return new org.apache.tomcat.jdbc.test.driver.ResultSet(this);
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to