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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ All notable changes to `phalcon/debugbar` are documented here. The format is bas
- Request history does not set its cookie when output started before the response, so `setcookie()` gives no warning. [#32](https://github.com/phalcon/debugbar/issues/32)
- `history.url` cannot be `/`. The documentation states that the history endpoint wins over an application route with the same path, for each HTTP method. [#32](https://github.com/phalcon/debugbar/issues/32)
- The documentation states that a browser in request history is one history cookie, so all its windows and tabs count as one for `history.max_browsers`. [#32](https://github.com/phalcon/debugbar/issues/32)
- The debug page exceptions implement `Phalcon\Debug\Contracts\DebugThrowable`. [#95](https://github.com/phalcon/debugbar/issues/95)

### Changed

Expand Down Expand Up @@ -91,6 +92,10 @@ All notable changes to `phalcon/debugbar` are documented here. The format is bas
- Share one renderer and one CSS block for the exceptions and logs panels, and show an exception with no trace as a plain line. [#108](https://github.com/phalcon/debugbar/issues/108)
- Test HTML writes, the collapse state and `localStorage` errors in the JS tests, and keep every listener in the fake DOM. [#103](https://github.com/phalcon/debugbar/issues/103)

### Removed

- `HistoryController::clearAction()` and `indexAction()`, `Phalcon\DebugBar\Version` and `CodeFragment::getMode()`, which nothing used. [#95](https://github.com/phalcon/debugbar/issues/95)

## [0.4.0](https://github.com/phalcon/debugbar/releases/tag/v0.4.0) (2026-07-14)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use Phalcon\Debug;

`listen()` does not see the exceptions of an ADR application, because the application catches them first. For an ADR application, see [ADR](#adr).

The page escapes every value it shows, including quotes, the class name and file paths. A byte that is not valid UTF-8 shows as `�` (U+FFFD), so the rest of the message still shows. A frame from `eval()`'d code, or from a file that cannot be read, shows no source lines. An exception that occurs while the page renders shows only its escaped message. `Phalcon\Debug\Dump` prints `*RECURSION*` for an object or an array that contains itself, and `[uninitialized]` for a typed property that has no value yet. To show an object, the page calls its `dump()` method only if that method is public, is not static, and has no required parameters. `setBlacklist()` removes a matching key at every depth, so `user[password]` does not show. The page discards each output buffer that starts after `Debug` is created, so create it before the application starts its own buffers. Under the message, the page shows each previous exception (`getPrevious()`) with its class, message, file and line. A framework class links to its API page on docs.phalcon.io for the Phalcon version that runs. `debugVar()` keeps the backtrace frames, but not their arguments and objects.
The page escapes every value it shows, including quotes, the class name and file paths. A byte that is not valid UTF-8 shows as `�` (U+FFFD), so the rest of the message still shows. A frame from `eval()`'d code, or from a file that cannot be read, shows no source lines. An exception that occurs while the page renders shows only its escaped message. `Phalcon\Debug\Dump` prints `*RECURSION*` for an object or an array that contains itself, and `[uninitialized]` for a typed property that has no value yet. To show an object, the page calls its `dump()` method only if that method is public, is not static, and has no required parameters. `setBlacklist()` removes a matching key at every depth, so `user[password]` does not show. The page discards each output buffer that starts after `Debug` is created, so create it before the application starts its own buffers. Under the message, the page shows each previous exception (`getPrevious()`) with its class, message, file and line. A framework class links to its API page on docs.phalcon.io for the Phalcon version that runs. `debugVar()` keeps the backtrace frames, but not their arguments and objects. Each exception of the debug page (`Exceptions\Exception`, `Exceptions\RequestHalted`, `Exceptions\RuntimeWarning`) implements `Phalcon\Debug\Contracts\DebugThrowable`, so one `catch` covers all of them.

The remainder of this document covers the debug bar.

Expand Down
9 changes: 0 additions & 9 deletions resources/assets/debug.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ body {
align-items: center; gap: 7px; font-size: 13px;
}
.btn:hover { color: var(--ink); border-color: var(--faint); }
.btn svg { opacity: .8; }
.version-badge {
font-size: 12px; color: var(--muted); background: var(--chip); border: 1px solid var(--border);
padding: 6px 11px; border-radius: 999px; text-decoration: none;
Expand Down Expand Up @@ -134,9 +133,6 @@ body {
.frame-call .cls a:hover { text-decoration: underline; }
.frame-call .op { color: var(--faint); }
.frame-call .fn { color: var(--ink); font-weight: 650; }
.frame-call .arg-str { color: var(--ok); }
.frame-call .arg-num { color: #b25000; }
html[data-theme="dark"] .frame-call .arg-num { color: #ff9e64; }
.frame.vendor .frame-call .fn { color: var(--muted); font-weight: 550; }
.tag-app {
font-size: 9px; font-weight: 700; letter-spacing: .4px; color: var(--ok); text-transform: uppercase;
Expand Down Expand Up @@ -196,11 +192,6 @@ html[data-theme="dark"] .frame-call .arg-num { color: #ff9e64; }
.grid tr:hover td { background: var(--panel-2); }
.grid .k { font-family: var(--mono); font-size: 12px; color: var(--muted); white-space: nowrap; width: 1%; }
.grid .v { font-family: var(--mono); font-size: 12px; word-break: break-word; }
.grid .v .t-str { color: var(--ok); }
.grid .v .t-num { color: #b25000; }
.grid .v .t-obj { color: #8250df; }
html[data-theme="dark"] .grid .v .t-num { color: #ff9e64; }
html[data-theme="dark"] .grid .v .t-obj { color: #d2a8ff; }

/* memory stats */
.stats { display: flex; gap: 14px; flex-wrap: wrap; }
Expand Down
2 changes: 1 addition & 1 deletion resources/assets/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
var cell = cells[i];
if (cell.getAttribute("data-hl")) { continue; }
var text = cell.textContent;
if (text.replace(/ /g, " ").trim() !== "") {
if (text.trim() !== "") {
cell.innerHTML = highlightPhp(text);
}
cell.setAttribute("data-hl", "1");
Expand Down
11 changes: 6 additions & 5 deletions resources/assets/debugbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,9 @@
return;
}

var data = payload.data || {};
var widgets = (payload.meta && payload.meta.widgets) || {};
// renderData() sets both before any panel reads them.
var data;
var widgets;

var bar = el('div', 'phalcon-debugbar-bar');
var historyBrowser = el('div', 'phalcon-debugbar-history-browser');
Expand Down Expand Up @@ -775,9 +776,9 @@
}

function renderData(nextPayload, preferredActive, requestMetadata) {
payload = nextPayload || {};
data = payload.data || {};
widgets = (payload.meta && payload.meta.widgets) || {};
var current = nextPayload || {};
data = current.data || {};
widgets = (current.meta && current.meta.widgets) || {};
tabs.innerHTML = '';
body.innerHTML = '';
body.style.display = 'none';
Expand Down
4 changes: 2 additions & 2 deletions resources/assets/debugbar.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/Debug/Contracts/DebugThrowable.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
use Throwable as BaseThrowable;

/**
* Catch-all marker implemented by every exception this package throws, so
* integrators can catch `Throwable` to trap anything from the bar.
* Catch-all marker implemented by every exception of the debug page
* (`Phalcon\Debug`), so integrators can catch `DebugThrowable` to trap
* anything from it.
*/
interface DebugThrowable extends BaseThrowable
{
Expand Down
3 changes: 2 additions & 1 deletion src/Debug/Exceptions/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@

namespace Phalcon\Debug\Exceptions;

use Phalcon\Debug\Contracts\DebugThrowable;
use Phalcon\Support\Exception as SupportException;

/**
* Exceptions thrown in Phalcon\Debug will use this class
*/
class Exception extends SupportException
class Exception extends SupportException implements DebugThrowable
{
}
4 changes: 3 additions & 1 deletion src/Debug/Exceptions/RuntimeWarning.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace Phalcon\Debug\Exceptions;

class RuntimeWarning extends \ErrorException
use Phalcon\Debug\Contracts\DebugThrowable;

class RuntimeWarning extends \ErrorException implements DebugThrowable
{
}
6 changes: 0 additions & 6 deletions src/Debug/Report/CodeFragment.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ final class CodeFragment
* @param array<int, string> $lines
*/
public function __construct(
private readonly string $mode,
private readonly int $firstLine,
private readonly int $line,
private readonly int $lastLine,
Expand Down Expand Up @@ -53,9 +52,4 @@ public function getLines(): array
{
return $this->lines;
}

public function getMode(): string
{
return $this->mode;
}
}
4 changes: 1 addition & 3 deletions src/Debug/ReportBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,12 @@ private function buildFragment(string $file, int $line, bool $showFileFragment):
$firstLine = ($beforeLine < 1) ? 1 : $beforeLine;
$afterLine = $line + 5;
$lastLine = ($afterLine > $numberLines) ? $numberLines : $afterLine;
$mode = 'fragment';
} else {
$firstLine = 1;
$lastLine = $numberLines;
$mode = 'full';
}

return new CodeFragment($mode, $firstLine, $line, $lastLine, $lines);
return new CodeFragment($firstLine, $line, $lastLine, $lines);
}

/**
Expand Down
10 changes: 0 additions & 10 deletions src/DebugBar/Controllers/HistoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,6 @@ public function __construct(
$this->handler = new HistoryHandler($history, $accessGate, $historyRequest, $historyResponse);
}

public function clearAction(): ResponseInterface
{
return $this->handler->clear();
}

public function indexAction(): ResponseInterface
{
return $this->handler->index();
}

public function openAction(): ResponseInterface
{
return $this->handler->open();
Expand Down
2 changes: 1 addition & 1 deletion src/DebugBar/History/FilesystemHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public function get(string $id): ?array
if (null === $directory) {
return null;
}
$file = $directory . '/' . basename($id) . '.json';
$file = $directory . '/' . $id . '.json';
if ($this->isExpired($file)) {
$this->removeEntry($file);
$this->removeDirectoryIfEmpty($directory);
Expand Down
27 changes: 0 additions & 27 deletions src/DebugBar/Version.php

This file was deleted.

43 changes: 43 additions & 0 deletions tests/Unit/Debug/Contracts/DebugThrowableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* This file is part of the Phalcon Framework.
*
* (c) Phalcon Team <team@phalcon.io>
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Phalcon\Tests\Unit\Debug\Contracts;

use Phalcon\Debug\Contracts\DebugThrowable;
use Phalcon\Debug\Exceptions\Exception;
use Phalcon\Debug\Exceptions\RequestHalted;
use Phalcon\Debug\Exceptions\RuntimeWarning;
use Phalcon\Talon\PHPUnit\AbstractUnitTestCase;
use PHPUnit\Framework\Attributes\DataProvider;
use Throwable;

final class DebugThrowableTest extends AbstractUnitTestCase
{
/**
* @return array<string, array{0: Throwable}>
*/
public static function throwableProvider(): array
{
return [
'Exception' => [new Exception('failed')],
'RequestHalted' => [new RequestHalted()],
'RuntimeWarning' => [new RuntimeWarning('warning')],
];
}

#[DataProvider('throwableProvider')]
public function testEachDebugPageExceptionIsADebugThrowable(Throwable $throwable): void
{
$this->assertInstanceOf(DebugThrowable::class, $throwable);
}
}
3 changes: 1 addition & 2 deletions tests/Unit/Debug/Renderer/HtmlRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ public function testRenderReplacesInvalidUtf8InASourceLine(): void
[],
'/app/x.php',
1,
new CodeFragment('fragment', 1, 1, 1, ["\$name = 'caf\xE9';\n"])
new CodeFragment(1, 1, 1, ["\$name = 'caf\xE9';\n"])
),
]
);
Expand Down Expand Up @@ -370,7 +370,6 @@ public function testTemplatesFallThrough(): void
private function buildReport(): ExceptionReport
{
$fragment = new CodeFragment(
'fragment',
3,
4,
5,
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/Debug/Report/BacktraceItemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function testDefaultsForMinimalFrame(): void

public function testGettersReturnConstructorValues(): void
{
$fragment = new CodeFragment('full', 1, 4, 9, ["<?php\n", "echo 1;\n"]);
$fragment = new CodeFragment(1, 4, 9, ["<?php\n", "echo 1;\n"]);

$item = new BacktraceItem(
'myFunction',
Expand Down
3 changes: 1 addition & 2 deletions tests/Unit/Debug/Report/CodeFragmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ final class CodeFragmentTest extends AbstractUnitTestCase
{
public function testGettersReturnConstructorValues(): void
{
$fragment = new CodeFragment('fragment', 3, 5, 9, ["<?php\n", "echo 1;\n"]);
$fragment = new CodeFragment(3, 5, 9, ["<?php\n", "echo 1;\n"]);

$this->assertSame('fragment', $fragment->getMode());
$this->assertSame(3, $fragment->getFirstLine());
$this->assertSame(5, $fragment->getLine());
$this->assertSame(9, $fragment->getLastLine());
Expand Down
2 changes: 0 additions & 2 deletions tests/Unit/Debug/ReportBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ public function testFragmentModeFragment(): void
/** @var CodeFragment $fragment */
$fragment = $method->invoke($builder, $file, 20, true);

$this->assertSame('fragment', $fragment->getMode());
$this->assertSame(13, $fragment->getFirstLine());
$this->assertSame(20, $fragment->getLine());
$this->assertSame(25, $fragment->getLastLine());
Expand All @@ -219,7 +218,6 @@ public function testFragmentModeFull(): void
/** @var CodeFragment $fragment */
$fragment = $method->invoke($builder, $file, 20, false);

$this->assertSame('full', $fragment->getMode());
$this->assertSame(1, $fragment->getFirstLine());
$this->assertSame(20, $fragment->getLine());
$this->assertSame(30, $fragment->getLastLine());
Expand Down
Loading
Loading