Liquibase is a tool for managing and executing database changes.
—
This document covers Liquibase's comprehensive exception hierarchy and error management system for handling various failure scenarios.
// Base exceptions
import liquibase.exception.LiquibaseException;
// Database exceptions
import liquibase.exception.DatabaseException;
import liquibase.exception.DatabaseHistoryException;
import liquibase.exception.LockException;
// Validation exceptions
import liquibase.exception.ValidationFailedException;
import liquibase.exception.ValidationErrors;
import liquibase.exception.CommandValidationException;
// Parsing exceptions
import liquibase.exception.ChangeLogParseException;
import liquibase.exception.LiquibaseParseException;
import liquibase.exception.UnknownChangelogFormatException;
// Execution exceptions
import liquibase.exception.CommandExecutionException;
import liquibase.exception.MigrationFailedException;
import liquibase.exception.RollbackFailedException;
import liquibase.exception.RollbackImpossibleException;
// Precondition exceptions
import liquibase.exception.PreconditionFailedException;
import liquibase.exception.PreconditionErrorException;
// Setup and configuration exceptions
import liquibase.exception.SetupException;
import liquibase.exception.UnexpectedLiquibaseException;The base exception class for all Liquibase-related errors.
/**
* Base exception for all Liquibase errors
*/
public class LiquibaseException extends Exception {
/**
* Create exception with message
* @param message Error message
*/
public LiquibaseException(String message)
/**
* Create exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public LiquibaseException(String message, Throwable cause)
/**
* Create exception with cause only
* @param cause Underlying cause
*/
public LiquibaseException(Throwable cause)
}General database-related errors including connection and SQL execution problems.
/**
* Exception for database-related errors
*/
public class DatabaseException extends LiquibaseException {
/**
* Create database exception with message
* @param message Error message describing database issue
*/
public DatabaseException(String message)
/**
* Create database exception with message and cause
* @param message Error message
* @param cause Underlying database exception (often SQLException)
*/
public DatabaseException(String message, Throwable cause)
}Errors related to Liquibase's database history tracking tables.
/**
* Exception for database history table errors
*/
public class DatabaseHistoryException extends DatabaseException {
/**
* Create history exception with message
* @param message Error message related to history tracking
*/
public DatabaseHistoryException(String message)
/**
* Create history exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public DatabaseHistoryException(String message, Throwable cause)
}Errors related to database locking mechanisms for preventing concurrent migrations.
/**
* Exception for database locking errors
*/
public class LockException extends LiquibaseException {
/**
* Create lock exception with message
* @param message Error message related to database locking
*/
public LockException(String message)
/**
* Create lock exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public LockException(String message, Throwable cause)
}Thrown when changelog or changeset validation fails.
/**
* Exception for validation failures
*/
public class ValidationFailedException extends LiquibaseException {
/**
* Create validation exception with message
* @param message Validation failure description
*/
public ValidationFailedException(String message)
/**
* Create validation exception with validation errors
* @param validationErrors Collection of validation errors
*/
public ValidationFailedException(ValidationErrors validationErrors)
/**
* Get validation errors if available
* @return ValidationErrors object, or null
*/
public ValidationErrors getValidationErrors()
}Container for multiple validation error messages.
/**
* Collection of validation errors
*/
public class ValidationErrors {
/**
* Check if any errors exist
* @return true if validation errors were found
*/
public boolean hasErrors()
/**
* Get list of error messages
* @return List of validation error messages
*/
public List<String> getErrorMessages()
/**
* Add validation error message
* @param message Error message to add
*/
public void addError(String message)
/**
* Get count of validation errors
* @return Number of validation errors
*/
public int getErrorCount()
}Validation errors specific to command execution and arguments.
/**
* Exception for command validation errors
*/
public class CommandValidationException extends ValidationFailedException {
/**
* Create command validation exception
* @param message Command validation error message
*/
public CommandValidationException(String message)
/**
* Create command validation exception with cause
* @param message Error message
* @param cause Underlying cause
*/
public CommandValidationException(String message, Throwable cause)
}Errors encountered while parsing changelog files.
/**
* Exception for changelog parsing errors
*/
public class ChangeLogParseException extends LiquibaseParseException {
/**
* Create parse exception with message
* @param message Parsing error description
*/
public ChangeLogParseException(String message)
/**
* Create parse exception with message and cause
* @param message Error message
* @param cause Underlying parsing exception
*/
public ChangeLogParseException(String message, Throwable cause)
}General parsing errors for various Liquibase file formats.
/**
* Exception for general parsing errors
*/
public class LiquibaseParseException extends LiquibaseException {
/**
* Create parse exception with message
* @param message Parsing error message
*/
public LiquibaseParseException(String message)
/**
* Create parse exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public LiquibaseParseException(String message, Throwable cause)
}Thrown when Liquibase encounters an unsupported changelog file format.
/**
* Exception for unknown changelog format
*/
public class UnknownChangelogFormatException extends ChangeLogParseException {
/**
* Create unknown format exception
* @param message Description of unknown format
*/
public UnknownChangelogFormatException(String message)
}Errors during command execution in the modern command framework.
/**
* Exception for command execution failures
*/
public class CommandExecutionException extends LiquibaseException {
/**
* Create command execution exception
* @param message Command execution error message
*/
public CommandExecutionException(String message)
/**
* Create command execution exception with cause
* @param message Error message
* @param cause Underlying cause of execution failure
*/
public CommandExecutionException(String message, Throwable cause)
}Errors during database migration execution.
/**
* Exception for migration execution failures
*/
public class MigrationFailedException extends LiquibaseException {
/**
* Create migration exception with message
* @param message Migration failure description
*/
public MigrationFailedException(String message)
/**
* Create migration exception with message and cause
* @param message Error message
* @param cause Underlying cause of migration failure
*/
public MigrationFailedException(String message, Throwable cause)
}Errors during rollback operations.
/**
* Exception for rollback execution failures
*/
public class RollbackFailedException extends LiquibaseException {
/**
* Create rollback exception with message
* @param message Rollback failure description
*/
public RollbackFailedException(String message)
/**
* Create rollback exception with message and cause
* @param message Error message
* @param cause Underlying cause of rollback failure
*/
public RollbackFailedException(String message, Throwable cause)
}Thrown when a rollback operation cannot be performed due to irreversible changes.
/**
* Exception when rollback is not possible
*/
public class RollbackImpossibleException extends RollbackFailedException {
/**
* Create rollback impossible exception
* @param message Explanation of why rollback is impossible
*/
public RollbackImpossibleException(String message)
/**
* Create rollback impossible exception with cause
* @param message Error message
* @param cause Underlying cause
*/
public RollbackImpossibleException(String message, Throwable cause)
}Thrown when preconditions defined in changesets fail.
/**
* Exception for precondition check failures
*/
public class PreconditionFailedException extends LiquibaseException {
/**
* Create precondition exception with message
* @param message Precondition failure description
*/
public PreconditionFailedException(String message)
/**
* Create precondition exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public PreconditionFailedException(String message, Throwable cause)
}Errors encountered while evaluating preconditions (different from precondition failures).
/**
* Exception for precondition evaluation errors
*/
public class PreconditionErrorException extends LiquibaseException {
/**
* Create precondition error exception
* @param message Precondition evaluation error message
*/
public PreconditionErrorException(String message)
/**
* Create precondition error exception with cause
* @param message Error message
* @param cause Underlying cause
*/
public PreconditionErrorException(String message, Throwable cause)
}Errors during Liquibase initialization and setup.
/**
* Exception for setup and initialization errors
*/
public class SetupException extends LiquibaseException {
/**
* Create setup exception with message
* @param message Setup error description
*/
public SetupException(String message)
/**
* Create setup exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public SetupException(String message, Throwable cause)
}Runtime errors that are unexpected and typically indicate bugs.
/**
* Exception for unexpected runtime errors
*/
public class UnexpectedLiquibaseException extends RuntimeException {
/**
* Create unexpected exception with message
* @param message Unexpected error description
*/
public UnexpectedLiquibaseException(String message)
/**
* Create unexpected exception with message and cause
* @param message Error message
* @param cause Underlying cause
*/
public UnexpectedLiquibaseException(String message, Throwable cause)
/**
* Create unexpected exception with cause only
* @param cause Underlying cause
*/
public UnexpectedLiquibaseException(Throwable cause)
}import liquibase.Liquibase;
import liquibase.exception.*;
try {
// Execute Liquibase operation
Liquibase liquibase = new Liquibase("changelog.xml", resourceAccessor, database);
liquibase.update((String) null);
} catch (DatabaseException e) {
System.err.println("Database error: " + e.getMessage());
// Handle database connectivity or SQL issues
} catch (ValidationFailedException e) {
System.err.println("Validation failed: " + e.getMessage());
// Check for detailed validation errors
ValidationErrors errors = e.getValidationErrors();
if (errors != null && errors.hasErrors()) {
for (String error : errors.getErrorMessages()) {
System.err.println(" - " + error);
}
}
} catch (ChangeLogParseException e) {
System.err.println("Changelog parsing error: " + e.getMessage());
// Handle XML/YAML/JSON parsing issues
} catch (MigrationFailedException e) {
System.err.println("Migration failed: " + e.getMessage());
// Handle changeset execution failures
} catch (LiquibaseException e) {
System.err.println("General Liquibase error: " + e.getMessage());
// Handle any other Liquibase-specific errors
}import liquibase.command.CommandScope;
import liquibase.command.CommandResults;
import liquibase.exception.CommandExecutionException;
import liquibase.exception.CommandValidationException;
try {
CommandScope updateCommand = new CommandScope("update")
.addArgumentValue("changelogFile", "db/changelog/db.changelog-master.xml")
.addArgumentValue("url", "jdbc:h2:mem:test")
.addArgumentValue("username", "sa")
.addArgumentValue("password", "");
CommandResults results = updateCommand.execute();
} catch (CommandValidationException e) {
System.err.println("Command validation error: " + e.getMessage());
// Handle invalid command arguments
} catch (CommandExecutionException e) {
System.err.println("Command execution failed: " + e.getMessage());
// Check for nested exceptions
Throwable cause = e.getCause();
if (cause instanceof DatabaseException) {
System.err.println("Underlying database error: " + cause.getMessage());
} else if (cause instanceof ValidationFailedException) {
System.err.println("Underlying validation error: " + cause.getMessage());
}
}try {
liquibase.rollback("version-1.0", "production");
} catch (RollbackImpossibleException e) {
System.err.println("Rollback impossible: " + e.getMessage());
// Handle cases where rollback cannot be performed
// May need manual intervention or different approach
} catch (RollbackFailedException e) {
System.err.println("Rollback failed: " + e.getMessage());
// Handle rollback execution failures
// Database may be in inconsistent state
} catch (DatabaseException e) {
System.err.println("Database error during rollback: " + e.getMessage());
// Handle database connectivity issues during rollback
}try {
liquibase.update((String) null);
} catch (LockException e) {
System.err.println("Database lock error: " + e.getMessage());
// Check if another process is running
try {
DatabaseChangeLogLock[] locks = liquibase.listLocks();
if (locks.length > 0) {
System.err.println("Found " + locks.length + " active locks:");
for (DatabaseChangeLogLock lock : locks) {
System.err.println(" Lock ID: " + lock.getId());
System.err.println(" Locked by: " + lock.getLockedBy());
System.err.println(" Lock time: " + lock.getLockGranted());
}
}
// Optionally force release locks (use with caution)
// liquibase.forceReleaseLocks();
} catch (LiquibaseException lockCheckException) {
System.err.println("Could not check locks: " + lockCheckException.getMessage());
}
}public class LiquibaseErrorHandler {
public void handleLiquibaseOperation(Runnable operation) {
try {
operation.run();
} catch (ValidationFailedException e) {
handleValidationError(e);
} catch (ChangeLogParseException e) {
handleParsingError(e);
} catch (DatabaseException e) {
handleDatabaseError(e);
} catch (MigrationFailedException e) {
handleMigrationError(e);
} catch (RollbackFailedException e) {
handleRollbackError(e);
} catch (LockException e) {
handleLockError(e);
} catch (CommandExecutionException e) {
handleCommandError(e);
} catch (LiquibaseException e) {
handleGeneralError(e);
} catch (UnexpectedLiquibaseException e) {
handleUnexpectedError(e);
}
}
private void handleValidationError(ValidationFailedException e) {
System.err.println("=== Validation Error ===");
System.err.println("Message: " + e.getMessage());
ValidationErrors errors = e.getValidationErrors();
if (errors != null && errors.hasErrors()) {
System.err.println("Validation errors (" + errors.getErrorCount() + "):");
for (String error : errors.getErrorMessages()) {
System.err.println(" - " + error);
}
}
}
private void handleParsingError(ChangeLogParseException e) {
System.err.println("=== Parsing Error ===");
System.err.println("Message: " + e.getMessage());
if (e instanceof UnknownChangelogFormatException) {
System.err.println("Unknown changelog format detected.");
System.err.println("Ensure changelog file has correct extension (.xml, .yaml, .json, .sql)");
}
Throwable cause = e.getCause();
if (cause != null) {
System.err.println("Underlying cause: " + cause.getMessage());
}
}
private void handleDatabaseError(DatabaseException e) {
System.err.println("=== Database Error ===");
System.err.println("Message: " + e.getMessage());
if (e instanceof DatabaseHistoryException) {
System.err.println("Issue with Liquibase tracking tables.");
System.err.println("Check DATABASECHANGELOG and DATABASECHANGELOGLOCK tables.");
}
Throwable cause = e.getCause();
if (cause instanceof SQLException) {
SQLException sqlEx = (SQLException) cause;
System.err.println("SQL Error Code: " + sqlEx.getErrorCode());
System.err.println("SQL State: " + sqlEx.getSQLState());
}
}
private void handleMigrationError(MigrationFailedException e) {
System.err.println("=== Migration Error ===");
System.err.println("Message: " + e.getMessage());
System.err.println("Migration failed during execution.");
System.err.println("Database may be in partially updated state.");
System.err.println("Review failed changeset and fix before retrying.");
}
private void handleRollbackError(RollbackFailedException e) {
System.err.println("=== Rollback Error ===");
System.err.println("Message: " + e.getMessage());
if (e instanceof RollbackImpossibleException) {
System.err.println("Rollback impossible - changes may be irreversible.");
System.err.println("Manual intervention may be required.");
} else {
System.err.println("Rollback execution failed.");
System.err.println("Database may be in inconsistent state.");
}
}
private void handleLockError(LockException e) {
System.err.println("=== Lock Error ===");
System.err.println("Message: " + e.getMessage());
System.err.println("Another Liquibase process may be running.");
System.err.println("Wait for other process to complete or force release locks.");
}
private void handleCommandError(CommandExecutionException e) {
System.err.println("=== Command Error ===");
System.err.println("Message: " + e.getMessage());
Throwable cause = e.getCause();
if (cause != null) {
System.err.println("Caused by: " + cause.getClass().getSimpleName() +
": " + cause.getMessage());
}
}
private void handleGeneralError(LiquibaseException e) {
System.err.println("=== General Liquibase Error ===");
System.err.println("Message: " + e.getMessage());
System.err.println("Type: " + e.getClass().getSimpleName());
}
private void handleUnexpectedError(UnexpectedLiquibaseException e) {
System.err.println("=== Unexpected Error (Possible Bug) ===");
System.err.println("Message: " + e.getMessage());
System.err.println("This may indicate a bug in Liquibase.");
System.err.println("Consider reporting this error with full stack trace.");
e.printStackTrace();
}
}public class LiquibaseRecovery {
public void attemptRecovery(Liquibase liquibase) {
try {
// First try to release any stale locks
liquibase.forceReleaseLocks();
// Validate changelog
liquibase.validate();
// Attempt operation again
liquibase.update((String) null);
} catch (LockException e) {
System.err.println("Could not release locks: " + e.getMessage());
} catch (ValidationFailedException e) {
System.err.println("Changelog validation still failing after lock release");
// Manual intervention required
} catch (DatabaseException e) {
System.err.println("Database connectivity issues persist");
// Check database connection and credentials
} catch (LiquibaseException e) {
System.err.println("Recovery failed: " + e.getMessage());
// Manual investigation required
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-liquibase--liquibase-core