com.scalar.db.sql.springdata.ScalarDbExceptionTranslator Maven / Gradle / Ivy
package com.scalar.db.sql.springdata;
import com.scalar.db.exception.transaction.TransactionException;
import com.scalar.db.sql.exception.SqlException;
import com.scalar.db.sql.springdata.exception.ScalarDbNonTransientException;
import com.scalar.db.sql.springdata.exception.ScalarDbTransientException;
import com.scalar.db.sql.springdata.exception.ScalarDbUnknownTransactionStateException;
import java.sql.SQLException;
import java.sql.SQLNonTransientException;
import java.sql.SQLTransientException;
import java.util.Optional;
import javax.annotation.Nonnull;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
public class ScalarDbExceptionTranslator extends AbstractFallbackSQLExceptionTranslator {
public ScalarDbExceptionTranslator(SQLExceptionTranslator delegate) {
super();
setFallbackTranslator(delegate);
}
@Override
protected DataAccessException doTranslate(
@Nonnull String task, String sql, @Nonnull SQLException exception) {
// The logic of this method is
// - Return ScalarDbUnknownTransactionStateException as the highest priority if
// UnknownTransactionStatusException is contained in the exception cause chain
// - Return ScalarDbNonTransientException or ScalarDbTransientException if the exception is
// SQLNonTransientException or SQLTransientException, respectively
// - Fallback to the original exception translation logic
Optional transactionId = Optional.empty();
Throwable e = exception;
while (e != null) {
// Keep a transaction ID if exists in the exception
if (!transactionId.isPresent()) {
if (e instanceof TransactionException) {
TransactionException te = (TransactionException) e;
transactionId = te.getTransactionId();
} else if (e instanceof SqlException) {
SqlException se = (SqlException) e;
transactionId = se.getTransactionId();
}
}
// Don't return immediately even if SQLNonTransientException or SQLTransientException is found
// as UnknownTransactionStatusException can be found later in the exception cause chain
if (e instanceof com.scalar.db.sql.exception.UnknownTransactionStatusException) {
return new ScalarDbUnknownTransactionStateException(
exception.getMessage(), exception, transactionId.orElse(null));
}
e = e.getCause();
}
if (exception instanceof SQLNonTransientException) {
return new ScalarDbNonTransientException(
exception.getMessage(), exception, transactionId.orElse(null));
}
if (exception instanceof SQLTransientException) {
return new ScalarDbTransientException(
exception.getMessage(), exception, transactionId.orElse(null));
}
// Fallback to the next delegate
return null;
}
}