Skip to content

Commit

Permalink
TrapHandle: add once() and times() method to limit count of dumps;
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Nov 25, 2023
1 parent bba2d9c commit 87c1361
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 11 deletions.
66 changes: 55 additions & 11 deletions src/Client/TrapHandle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@

namespace Buggregator\Trap\Client;

use Buggregator\Trap\Client\TrapHandle\Counter;
use Symfony\Component\VarDumper\Caster\TraceStub;
use Symfony\Component\VarDumper\VarDumper;

/**
* @internal
* @psalm-internal Buggregator\Trap
*/
final class TrapHandle
{
private array $values;
private bool $haveToSend = true;
private int $times = 0;
private string $timesCounterKey = '';

public static function fromArray(array $array): self
{
$new = new self();
$new->values = $array;
return $new;
return new self($array);
}

/**
* Dump only if the condition is true.
* The check is performed immediately upon declaration.
*/
public function if(bool|callable $condition): self
{
Expand All @@ -36,9 +36,36 @@ public function if(bool|callable $condition): self
return $this;
}

/**
* Dump only $times times.
* The counter isn't incremented if the dump is not sent (any other condition is not met).
* It might be useful for debugging in loops, recursive or just multiple function calls.
*
* @param positive-int $times
* @param bool $fullStack If true, the counter is incremented for each stack trace, not for the line.
*/
public function times(int $times, bool $fullStack = false): self
{
$this->times = $times;
$this->timesCounterKey = (\serialize(
$fullStack
? $this->stackTrace()
: $this->stackTrace()[0]

Check failure on line 53 in src/Client/TrapHandle.php

View workflow job for this annotation

GitHub Actions / Psalm Validation (PHP 8.2, OS ubuntu-latest)

InvalidArrayOffset

src/Client/TrapHandle.php:53:19: InvalidArrayOffset: Cannot access value on variable using offset value of '0', expecting string (see https://psalm.dev/115)
));
return $this;
}

/**
* Dump values only once.
*/
public function once(): self
{
return $this->times(1);
}

public function __destruct()
{
$this->haveToSend and $this->sendUsingDump();
$this->haveToSend() and $this->sendUsingDump();
}

private function sendUsingDump(): void
Expand Down Expand Up @@ -88,24 +115,41 @@ private function sendUsingDump(): void
* args?: array
* }>
*/
private function stackTrace(string $baseDir): array
private function stackTrace(string $baseDir = ''): array
{
$dir = \getcwd() . \DIRECTORY_SEPARATOR;
$dir = $baseDir . \DIRECTORY_SEPARATOR;
$cwdLen = \strlen($dir);
// Replace paths with relative paths
$stack = [];
foreach (\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
if (($frame['class'] ?? null) === __CLASS__) {
if (($frame['file'] ?? null) === __FILE__) {
continue;
}

// Convert absolute paths to relative ones
isset($frame['file']) && \str_starts_with($frame['file'], $dir)
$cwdLen > 1 && isset($frame['file']) && \str_starts_with($frame['file'], $dir)
and $frame['file'] = '.' . \DIRECTORY_SEPARATOR . \substr($frame['file'], $cwdLen);

$stack[] = $frame;
}

return $stack;

Check failure on line 135 in src/Client/TrapHandle.php

View workflow job for this annotation

GitHub Actions / Psalm Validation (PHP 8.2, OS ubuntu-latest)

InvalidReturnStatement

src/Client/TrapHandle.php:135:16: InvalidReturnStatement: The inferred type 'list<array{args?: list<mixed>, class?: class-string, file?: string, function: string, line?: int, object?: object, type?: string}>' does not match the declared return type 'array<string, array{args?: array<array-key, mixed>, class?: class-string, file?: non-empty-string, function?: non-empty-string, line?: int<0, max>, object?: object, type?: non-empty-string}>' for Buggregator\Trap\Client\TrapHandle::stackTrace (see https://psalm.dev/128)
}

private function __construct(
private array $values,
) {
}

private function haveToSend(): bool
{
if (!$this->haveToSend) {
return false;
}

if ($this->times > 0) {
return Counter::checkAndIncrement($this->timesCounterKey, $this->times);
}

return true;
}
}
26 changes: 26 additions & 0 deletions src/Client/TrapHandle/Counter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Client\TrapHandle;

final class Counter
{
/** @var array<non-empty-string, int<0, max>> */
private static array $counters = [];

/**
* Returns true if the counter of related stack trace is less than $times. In this case, the counter is incremented.
*/
public static function checkAndIncrement(string $key, int $times): bool
{
self::$counters[$key] ??= 0;

Check failure on line 17 in src/Client/TrapHandle/Counter.php

View workflow job for this annotation

GitHub Actions / Psalm Validation (PHP 8.2, OS ubuntu-latest)

PropertyTypeCoercion

src/Client/TrapHandle/Counter.php:17:9: PropertyTypeCoercion: Buggregator\Trap\Client\TrapHandle\Counter::$counters expects 'array<non-empty-string, int<0, max>>', parent type 'non-empty-array<string, int<0, max>>' provided (see https://psalm.dev/198)

if (self::$counters[$key] < $times) {
self::$counters[$key]++;

Check failure on line 20 in src/Client/TrapHandle/Counter.php

View workflow job for this annotation

GitHub Actions / Psalm Validation (PHP 8.2, OS ubuntu-latest)

PropertyTypeCoercion

src/Client/TrapHandle/Counter.php:20:13: PropertyTypeCoercion: Buggregator\Trap\Client\TrapHandle\Counter::$counters expects 'array<non-empty-string, int<0, max>>', parent type 'non-empty-array<string, int<0, max>>' provided (see https://psalm.dev/198)
return true;
}

return false;
}
}

0 comments on commit 87c1361

Please sign in to comment.