diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php index d025453f74ba..9060931d4c55 100644 --- a/system/Database/BaseConnection.php +++ b/system/Database/BaseConnection.php @@ -1188,9 +1188,11 @@ public function prepare(Closure $func, array $options = []) $this->pretend(); - $sql = $func($this); - - $this->pretend(false); + try { + $sql = $func($this); + } finally { + $this->pretend(false); + } if ($sql instanceof QueryInterface) { $sql = $sql->getOriginalQuery(); diff --git a/tests/system/Database/Live/PretendTest.php b/tests/system/Database/Live/PretendTest.php index b3e6506c1be6..c0548cc22f73 100644 --- a/tests/system/Database/Live/PretendTest.php +++ b/tests/system/Database/Live/PretendTest.php @@ -17,6 +17,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; use PHPUnit\Framework\Attributes\Group; +use RuntimeException; /** * @internal @@ -46,4 +47,23 @@ public function testPretendReturnsQueryObject(): void $this->assertInstanceOf(Query::class, $result); } + + public function testPrepareResetsPretendWhenClosureThrowsException(): void + { + $this->db->pretend(false); + + $invoked = false; + + try { + $this->db->prepare(static function () use (&$invoked): never { + $invoked = true; + + throw new RuntimeException('Error in prepare closure'); + }); + } catch (RuntimeException) { + } + + $this->assertTrue($invoked); + $this->assertFalse($this->db->pretend); + } }