From d9b63681a148b6afd4c10d0b314f92535588784b Mon Sep 17 00:00:00 2001 From: mscherer Date: Sun, 2 Nov 2025 14:18:07 +0100 Subject: [PATCH 1/2] Try to reproduce serialize issues --- src/ToolbarService.php | 25 ++++++++++++-- tests/TestCase/ToolbarServiceTest.php | 49 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/ToolbarService.php b/src/ToolbarService.php index 729fee5f..220013e7 100644 --- a/src/ToolbarService.php +++ b/src/ToolbarService.php @@ -291,10 +291,31 @@ public function saveData(ServerRequest $request, ResponseInterface $response): R foreach ($this->registry->loaded() as $name) { $panel = $this->registry->{$name}; try { - $content = serialize($panel->data()); + $data = $panel->data(); + + // Set error handler to catch warnings/errors during serialization + set_error_handler(function ($errno, $errstr) use ($name): void { + throw new Exception("Serialization error in panel '{$name}': {$errstr}"); + }); + + $content = serialize($data); + + restore_error_handler(); } catch (Exception $e) { + restore_error_handler(); + + $errorMessage = sprintf( + 'Failed to serialize data for panel "%s": %s', + $name, + $e->getMessage(), + ); + + Log::warning($errorMessage); + Log::debug('Panel data type: ' . gettype($data ?? null)); + $content = serialize([ - 'error' => $e->getMessage(), + 'error' => $errorMessage, + 'panel' => $name, ]); } $row->panels[] = $requests->Panels->newEntity([ diff --git a/tests/TestCase/ToolbarServiceTest.php b/tests/TestCase/ToolbarServiceTest.php index 596c6629..cde248f6 100644 --- a/tests/TestCase/ToolbarServiceTest.php +++ b/tests/TestCase/ToolbarServiceTest.php @@ -506,4 +506,53 @@ public function testIsEnabledForceEnableCallable() ]); $this->assertTrue($bar->isEnabled(), 'debug is off, panel is forced on'); } + + /** + * Test that saveData handles serialization errors gracefully + * + * @return void + */ + public function testSaveDataSerializationError() + { + $request = new Request([ + 'url' => '/articles', + 'environment' => ['REQUEST_METHOD' => 'GET'], + ]); + $response = new Response([ + 'statusCode' => 200, + 'type' => 'text/html', + 'body' => 'test

some text

', + ]); + + $bar = new ToolbarService($this->events, []); + $bar->loadPanels(); + + // Create a panel with unserializable data + $panel = $bar->registry()->load('DebugKit.TestApp\Panel\SimplePanel'); + // Mock the data() method to return something problematic + $panel->_data = ['closure' => fn () => 'test']; + + $row = $bar->saveData($request, $response); + $this->assertNotEmpty($row, 'Should save data even with serialization errors'); + + $requests = $this->getTableLocator()->get('DebugKit.Requests'); + $result = $requests->find() + ->orderBy(['Requests.requested_at' => 'DESC']) + ->contain('Panels') + ->first(); + + // Find the SimplePanel in the results + $simplePanel = null; + foreach ($result->panels as $p) { + if ($p->panel === 'SimplePanel') { + $simplePanel = $p; + break; + } + } + + $this->assertNotNull($simplePanel, 'SimplePanel should be present'); + $content = unserialize($simplePanel->content); + $this->assertArrayHasKey('error', $content, 'Should have error key'); + $this->assertStringContainsString('SimplePanel', $content['error'], 'Error should mention panel name'); + } } From 1eac4cd1affa7f4fb5efdd116fe848a74a2ffcfe Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Mon, 3 Nov 2025 20:05:49 +0100 Subject: [PATCH 2/2] fix tests --- composer.json | 2 +- tests/TestCase/ToolbarServiceTest.php | 10 +++++++--- tests/bootstrap.php | 4 ++-- tests/test_app/Panel/SimplePanel.php | 4 ++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index c2d51114..dcb1af41 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "require-dev": { "cakephp/authorization": "^3.0", "cakephp/cakephp-codesniffer": "^5.0", - "phpunit/phpunit": "^10.5.5 || ^11.1.3" + "phpunit/phpunit": "^10.5.32 || ^11.1.3" }, "suggest": { "ext-pdo_sqlite": "DebugKit needs to store panel data in a database. SQLite is simple and easy to use." diff --git a/tests/TestCase/ToolbarServiceTest.php b/tests/TestCase/ToolbarServiceTest.php index cde248f6..789d30f0 100644 --- a/tests/TestCase/ToolbarServiceTest.php +++ b/tests/TestCase/ToolbarServiceTest.php @@ -26,6 +26,7 @@ use Cake\TestSuite\TestCase; use DebugKit\Model\Entity\Request as RequestEntity; use DebugKit\Panel\SqlLogPanel; +use DebugKit\TestApp\Panel\SimplePanel; use DebugKit\ToolbarService; use PHPUnit\Framework\Attributes\DataProvider; @@ -528,9 +529,12 @@ public function testSaveDataSerializationError() $bar->loadPanels(); // Create a panel with unserializable data - $panel = $bar->registry()->load('DebugKit.TestApp\Panel\SimplePanel'); + /** @var SimplePanel $panel */ + $panel = $bar->registry()->load('DebugKit.TestApp\Panel\SimplePanel', [ + 'className' => SimplePanel::class, + ]); // Mock the data() method to return something problematic - $panel->_data = ['closure' => fn () => 'test']; + $panel->setData(['closure' => fn() => 'test']); $row = $bar->saveData($request, $response); $this->assertNotEmpty($row, 'Should save data even with serialization errors'); @@ -544,7 +548,7 @@ public function testSaveDataSerializationError() // Find the SimplePanel in the results $simplePanel = null; foreach ($result->panels as $p) { - if ($p->panel === 'SimplePanel') { + if ($p->panel === 'DebugKit.TestApp\Panel\SimplePanel') { $simplePanel = $p; break; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1f605002..e43e2036 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -71,9 +71,9 @@ ]); Cache::setConfig([ - '_cake_core_' => [ + '_cake_translations_' => [ 'engine' => 'File', - 'prefix' => 'cake_core_', + 'prefix' => 'cake_translations_', 'serialize' => true, ], '_cake_model_' => [ diff --git a/tests/test_app/Panel/SimplePanel.php b/tests/test_app/Panel/SimplePanel.php index fe688da8..692397f3 100644 --- a/tests/test_app/Panel/SimplePanel.php +++ b/tests/test_app/Panel/SimplePanel.php @@ -22,4 +22,8 @@ */ class SimplePanel extends DebugPanel { + public function setData(array $data): void + { + $this->_data = $data; + } }