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