Exception Handling

NuoDB supports mapping from common database errors to categorized SQL exceptions. This allows for better handling of specific SQL errors. There are two types of categorized SQL exceptions:

When a JDBC exception occurs, it includes a SQL State value to identify the type of error. The first two characters in the SQL State value indicate the class and the remaining characters indicate the subclass. For example, a deadlock has SQL State 40001, where 40 is the class and 001 is the subclass.

Non-Transient SQL Exceptions

A non-transient SQL exception is thrown when a retry of the same operation would fail unless the cause of the SQL exception is corrected. For example, when trying to insert a duplicate primary key. Upon receiving a non-transient SQL exception, the application can assume that the connection is still valid.

SQLState Class Non-Transient SQL Exception

08

SQLNonTransientConnectionException on initial attempt (i.e. Driver#connect())

0A

SQLFeatureNotSupportedException

22

SQLDataException

23

SQLIntegrityConstraintViolationException

28

SQLInvalidAuthorizationException

42

SQLSyntaxErrorException

Transient SQL Exceptions

A transient SQL exception is thrown when a previously failed operation might succeed when the operation is retried without any intervention by application-level functionality. For example, deadlock, query timeout, or loss of connection to the TE.

SQLState Class Transient SQL Exception

08

SQLTransientConnectionException on an attempt where we once had a connection but no longer do

40

SQLTransactionRollbackException — for example, due to deadlock

BatchUpdateException

BatchUpdateException supports exception chaining. Invoking getNextException() repeatedly on a BatchUpdateException object, will traverse the list of exceptions that were generated.

Here is an example catch clause for a BatchUpdateException:

   ....
    } catch (BatchUpdateException bue) {

        int[] updateCounts = bue.getUpdateCounts();
        SQLException exception = bue;
        for (int i = 0; i < updateCounts.length; i++) {
            System.out.println(
                "** BatchUpdateException updateCounts[" + i + "]=\"" +
                updateCounts[i] + "\"" );
            if (updateCounts[i] == java.sql.Statement.EXECUTE_FAILED) {
                exception = exception.getNextException();
                System.out.println("   SQLException \"" + exception + "\"");
            }
        }
    }
** BatchUpdateException updateCounts[0]="1" (1)
** BatchUpdateException updateCounts[1]="1"
** BatchUpdateException updateCounts[2]="-3"(2)
   SQLException "java.sql.SQLIntegrityConstraintViolationException: violation of constraint "GENDER""
** BatchUpdateException updateCounts[3]="1"
** BatchUpdateException updateCounts[4]="-3"(2)
   SQLException "java.sql.SQLIntegrityConstraintViolationException: duplicate value in unique index MEMBERS..PRIMARY_KEY, key = '4'"
** BatchUpdateException updateCounts[5]="1"
1 Six statements were executed by this batch update. In NuoDB, statements in a batch update are executed even if some statements encountered errors.
2 The third statement and the fifth statement in the batch resulted in the error.

Obtaining Error Information

To obtain more information about an error, use the SQLException.getErrorCode() function.

For example, to distinguish between a unique constraint violation and a check constraint violation, check the error code. For a unique constraint violation the error code is -27 and for a check constraint violation the error code is -45. For more information, see SQL Error Codes.

All the SQL States recognized by NuoDB are enumerated values on the com.nuodb.jdbc.SqlState enum.

For example:

try {
    preparedStatement.execute();
} catch (SQLException e) {
    if (e.getErrorCode() == SQLState.UNIQUE_DUPLICATE.getCode()) {
        System.err.println("Unexpected duplicate");
    } else if (e.getErrorCode() == SQLState.CONSTRAINT_ERROR.getCode()) {
        System.err.println("Constraint violation");
    } else {
        System.err.println("Unexpected error: \"" + e.getMessage() + "\"");
    }
}