3030import io .r2dbc .spi .R2dbcTimeoutException ;
3131import io .r2dbc .spi .R2dbcTransientException ;
3232import io .r2dbc .spi .R2dbcTransientResourceException ;
33+ import oracle .jdbc .OracleDatabaseException ;
3334
3435import java .sql .SQLException ;
3536import java .sql .SQLIntegrityConstraintViolationException ;
@@ -166,41 +167,42 @@ static R2dbcException toR2dbcException(SQLException sqlException) {
166167 final String message = sqlException .getMessage ();
167168 final String sqlState = sqlException .getSQLState ();
168169 final int errorCode = sqlException .getErrorCode ();
170+ final String sql = getSql (sqlException );
169171
170172 if (sqlException instanceof SQLNonTransientException ) {
171173 if (sqlException instanceof SQLSyntaxErrorException ) {
172174 return new R2dbcBadGrammarException (
173- message , sqlState , errorCode , sqlException );
175+ message , sqlState , errorCode , sql , sqlException );
174176 }
175177 else if (sqlException instanceof SQLIntegrityConstraintViolationException ) {
176178 return new R2dbcDataIntegrityViolationException (
177- message , sqlState , errorCode , sqlException );
179+ message , sqlState , errorCode , sql , sqlException );
178180 }
179181 else if (sqlException instanceof SQLNonTransientConnectionException ) {
180182 return new R2dbcNonTransientResourceException (
181- message , sqlState , errorCode , sqlException );
183+ message , sqlState , errorCode , sql , sqlException );
182184 }
183185 else {
184186 return new OracleR2dbcNonTransientException (
185- message , sqlState , errorCode , sqlException );
187+ message , sqlState , errorCode , sql , sqlException );
186188 }
187189 }
188190 else if (sqlException instanceof SQLTransientException ) {
189191 if (sqlException instanceof SQLTimeoutException ) {
190192 return new R2dbcTimeoutException (
191- message , sqlState , errorCode , sqlException );
193+ message , sqlState , errorCode , sql , sqlException );
192194 }
193195 else if (sqlException instanceof SQLTransactionRollbackException ) {
194196 return new R2dbcRollbackException (
195- message , sqlState , errorCode , sqlException );
197+ message , sqlState , errorCode , sql , sqlException );
196198 }
197199 else if (sqlException instanceof SQLTransientConnectionException ) {
198200 return new R2dbcTransientResourceException (
199- message , sqlState , errorCode , sqlException );
201+ message , sqlState , errorCode , sql , sqlException );
200202 }
201203 else {
202204 return new OracleR2dbcTransientException (
203- message , sqlState , errorCode , sqlException );
205+ message , sqlState , errorCode , sql , sqlException );
204206 }
205207 }
206208 else if (sqlException instanceof SQLRecoverableException ) {
@@ -209,11 +211,11 @@ else if (sqlException instanceof SQLRecoverableException) {
209211 // the connection is no longer valid. The R2dbcTransientResourceException
210212 // expresses the same conditions.
211213 return new R2dbcTransientResourceException (
212- message , sqlState , errorCode , sqlException );
214+ message , sqlState , errorCode , sql , sqlException );
213215 }
214216 else {
215217 return new OracleR2dbcException (
216- message , sqlState , errorCode , sqlException );
218+ message , sqlState , errorCode , sql , sqlException );
217219 }
218220 }
219221
@@ -293,8 +295,30 @@ static <T> T fromJdbc(ThrowingSupplier<T> supplier)
293295 * @return A new non-transient exception.
294296 */
295297 static R2dbcNonTransientException newNonTransientException (
296- String message , Throwable cause ) {
297- return new OracleR2dbcNonTransientException (message , null , 0 , cause );
298+ String message , String sql , Throwable cause ) {
299+ return new OracleR2dbcNonTransientException (message , null , 0 , sql , cause );
300+ }
301+
302+ /**
303+ * Returns the SQL command that caused a {@code sqlException}, if it is
304+ * available. This method is only implemented to support the case where the
305+ * exception is caused by a {@link oracle.jdbc.OracleDatabaseException}.
306+ * @param sqlException Exception to extract SQL from. Not null.
307+ * @return The SQL that caused the {@code sqlException}, of {@code null} if
308+ * the SQL is not available.
309+ */
310+ private static String getSql (SQLException sqlException ) {
311+ Throwable cause = sqlException .getCause ();
312+
313+ while (cause != null ) {
314+
315+ if (cause instanceof OracleDatabaseException )
316+ return ((OracleDatabaseException )cause ).getSql ();
317+
318+ cause = cause .getCause ();
319+ }
320+
321+ return null ;
298322 }
299323
300324 /**
@@ -368,17 +392,17 @@ default T get() throws R2dbcException {
368392 * concrete subclass must be defined. This subclass does not implement any
369393 * behavior that is specific to the Oracle driver.
370394 * </p><p>
371- * This subclass is defined so that {@link #toR2dbcException(SQLException)}
372- * can throw an instance of {@code R2dbcException} when mapping a
373- * {@link SQLException}.
395+ * This subclass is defined so that
396+ * {@link #toR2dbcException(SQLException)} can throw an instance of
397+ * {@code R2dbcException} when mapping a {@ link SQLException}.
374398 * </p>
375399 */
376400 private static final class OracleR2dbcException
377401 extends R2dbcException {
378402 private OracleR2dbcException (
379- String message , String sqlState , int errorCode ,
403+ String message , String sqlState , int errorCode , String sql ,
380404 SQLException sqlException ) {
381- super (message , sqlState , errorCode , sqlException );
405+ super (message , sqlState , errorCode , sql , sqlException );
382406 }
383407 }
384408
@@ -390,17 +414,18 @@ private OracleR2dbcException(
390414 * This subclass does implement any behavior that is specific to the
391415 * Oracle driver.
392416 * </p><p>
393- * This subclass is defined so that {@link #toR2dbcException(SQLException)}
394- * can throw an instance of {@code R2dbcTransientException} when mapping a
417+ * This subclass is defined so that
418+ * {@link #toR2dbcException(SQLException)} can throw an instance of
419+ * {@code R2dbcTransientException} when mapping a
395420 * {@link SQLTransientException}.
396421 * </p>
397422 */
398423 private static final class OracleR2dbcTransientException
399424 extends R2dbcTransientException {
400425 private OracleR2dbcTransientException (
401- String message , String sqlState , int errorCode ,
426+ String message , String sqlState , int errorCode , String sql ,
402427 SQLException sqlException ) {
403- super (message , sqlState , errorCode , sqlException );
428+ super (message , sqlState , errorCode , sql , sqlException );
404429 }
405430 }
406431
@@ -420,9 +445,9 @@ private OracleR2dbcTransientException(
420445 private static final class OracleR2dbcNonTransientException
421446 extends R2dbcNonTransientException {
422447 private OracleR2dbcNonTransientException (
423- String message , String sqlState , int errorCode ,
448+ String message , String sqlState , int errorCode , String sql ,
424449 Throwable cause ) {
425- super (message , sqlState , errorCode , cause );
450+ super (message , sqlState , errorCode , sql , cause );
426451 }
427452 }
428453
0 commit comments