Skip to content

Commit 2f5c77f

Browse files
committed
Run risky code in finally block
1 parent 61446f0 commit 2f5c77f

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/Connection.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,15 +1278,20 @@ public function lastInsertId($name = null)
12781278
public function transactional(Closure $func)
12791279
{
12801280
$this->beginTransaction();
1281+
1282+
$successful = false;
1283+
12811284
try {
12821285
$res = $func($this);
12831286
$this->commit();
12841287

1285-
return $res;
1286-
} catch (Throwable $e) {
1287-
$this->rollBack();
1288+
$successful = true;
12881289

1289-
throw $e;
1290+
return $res;
1291+
} finally {
1292+
if (! $successful) {
1293+
$this->rollBack();
1294+
}
12901295
}
12911296
}
12921297

tests/ConnectionTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,27 @@ public function testLegacySchemaManagerFactory(): void
10041004
$connection = DriverManager::getConnection(['driver' => 'sqlite3', 'memory' => true]);
10051005
self::assertInstanceOf(SqliteSchemaManager::class, $connection->createSchemaManager());
10061006
}
1007+
1008+
public function testItPreservesTheOriginalExceptionOnRollbackFailure(): void
1009+
{
1010+
$connection = new class (['memory' => true], new Driver\SQLite3\Driver()) extends Connection {
1011+
public function rollBack(): void
1012+
{
1013+
throw new Exception('Rollback exception');
1014+
}
1015+
};
1016+
1017+
try {
1018+
$connection->transactional(static function (): void {
1019+
throw new Exception('Original exception');
1020+
});
1021+
self::fail('Exception expected');
1022+
} catch (Exception $e) {
1023+
self::assertSame('Rollback exception', $e->getMessage());
1024+
self::assertNotNull($e->getPrevious());
1025+
self::assertSame('Original exception', $e->getPrevious()->getMessage());
1026+
}
1027+
}
10071028
}
10081029

10091030
interface ConnectDispatchEventListener

0 commit comments

Comments
 (0)