Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
25 changes: 23 additions & 2 deletions src/ToolbarService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down
53 changes: 53 additions & 0 deletions tests/TestCase/ToolbarServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -506,4 +507,56 @@ 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' => '<html><title>test</title><body><p>some text</p></body>',
]);

$bar = new ToolbarService($this->events, []);
$bar->loadPanels();

// Create a panel with unserializable data
/** @var SimplePanel $panel */
$panel = $bar->registry()->load('DebugKit.TestApp\Panel\SimplePanel', [
'className' => SimplePanel::class,
]);
// Mock the data() method to return something problematic
$panel->setData(['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 === 'DebugKit.TestApp\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');
}
}
4 changes: 2 additions & 2 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
]);

Cache::setConfig([
'_cake_core_' => [
'_cake_translations_' => [
'engine' => 'File',
'prefix' => 'cake_core_',
'prefix' => 'cake_translations_',
'serialize' => true,
],
'_cake_model_' => [
Expand Down
4 changes: 4 additions & 0 deletions tests/test_app/Panel/SimplePanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
*/
class SimplePanel extends DebugPanel
{
public function setData(array $data): void
{
$this->_data = $data;
}
}
Loading