diff --git a/src/Exception/CatastrophicMigrationException.php b/src/Exception/CatastrophicMigrationException.php new file mode 100644 index 000000000..bf28a308d --- /dev/null +++ b/src/Exception/CatastrophicMigrationException.php @@ -0,0 +1,14 @@ +additionalException; + } + + public function setAdditionalException(Throwable $additionalException): static + { + $this->additionalException = $additionalException; + + return $this; + } +} diff --git a/src/Exception/TransactionRollbackException.php b/src/Exception/TransactionRollbackException.php new file mode 100644 index 000000000..377799363 --- /dev/null +++ b/src/Exception/TransactionRollbackException.php @@ -0,0 +1,12 @@ +getMigration(); if ($migration->isTransactional()) { - //only rollback transaction if in transactional mode - TransactionHelper::rollbackIfInTransaction($this->connection); + try { + //only rollback transaction if in transactional mode + TransactionHelper::rollbackIfInTransaction($this->connection); + } catch (\Exception $transactionRollbackException) { + $this->logResult( + (new TransactionRollbackException( + 'The migration transaction could not be rolled back after an encountered exception during its execution.', + previous: $transactionRollbackException + ))->setAdditionalException($e), + $result, + $plan + ); + } } $plan->markAsExecuted($result); @@ -254,14 +267,27 @@ private function logResult(Throwable $e, ExecutionResult $result, MigrationPlan ], ); } elseif ($result->hasError()) { - $this->logger->error( - 'Migration {version} failed during {state}. Error: "{error}"', - [ - 'version' => (string) $plan->getVersion(), - 'error' => $e->getMessage(), - 'state' => $this->getExecutionStateAsString($result->getState()), - ], - ); + if ($e instanceof CatastrophicMigrationException) { + $this->logger->error( + 'Migration {version} failed catastrophically at {state} during the error handling routine.' + . ' Error: "{error}". Additional error: {additionalError}', + [ + 'version' => (string)$plan->getVersion(), + 'error' => $e->getMessage(), + 'additionalError' => $e->getAdditionalException()->getMessage(), + 'state' => $this->getExecutionStateAsString($result->getState()), + ], + ); + } else { + $this->logger->error( + 'Migration {version} failed during {state}. Error: "{error}"', + [ + 'version' => (string)$plan->getVersion(), + 'error' => $e->getMessage(), + 'state' => $this->getExecutionStateAsString($result->getState()), + ], + ); + } } }