Skip to content

Commit

Permalink
Create the Trap handle returned from a trap() call
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Nov 25, 2023
1 parent 46ae632 commit 5097ee1
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 44 deletions.
98 changes: 98 additions & 0 deletions src/Client/TrapHandle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Client;

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;

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

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

private function sendUsingDump(): void
{
\class_exists(VarDumper::class) or throw new \RuntimeException(
'VarDumper is not installed. Please install symfony/var-dumper package.'
);

// Set default values if not set
if (!isset($_SERVER['VAR_DUMPER_FORMAT'], $_SERVER['VAR_DUMPER_SERVER'])) {
$_SERVER['VAR_DUMPER_FORMAT'] = 'server';
// todo use the config file in the future
$_SERVER['VAR_DUMPER_SERVER'] = '127.0.0.1:9912';
}

// If there are no values - stack trace
if ($this->values === []) {
VarDumper::dump([
'cwd' => \getcwd(),
'trace' => new TraceStub(($this->stackTrace(\getcwd()))),
]);
return;
}

// Dump single value
if (\array_keys($this->values) === [0]) {
VarDumper::dump($this->values[0]);
return;
}

// Dump sequence of values
foreach ($this->values as $key => $value) {
/** @psalm-suppress TooManyArguments */
VarDumper::dump($value, $key);
}
}

/**
* @param string $baseDir Base directory for relative paths
* @return array<string, array{
* function?: non-empty-string,
* line?: int<0, max>,
* file?: non-empty-string,
* class?: class-string,
* object?: object,
* type?: non-empty-string,
* args?: array
* }>
*/
private function stackTrace(string $baseDir): array
{
$dir = \getcwd() . \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__) {
continue;
}

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

$stack[] = $frame;
}

return $stack;
}
}
50 changes: 6 additions & 44 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,27 @@

declare(strict_types=1);

use Buggregator\Trap\Client\TrapHandle;
use Buggregator\Trap\Support\Caster\EnumValue;
use Buggregator\Trap\Support\ProtobufCaster;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\Message;
use Google\Protobuf\Internal\RepeatedField;
use Symfony\Component\VarDumper\Caster\TraceStub;
use Symfony\Component\VarDumper\Cloner\AbstractCloner;
use Symfony\Component\VarDumper\VarDumper;

if (!\function_exists('trap')) {
try {
/**
* Configure VarDumper to dump values to the local server.
* If there are no values - dump stack trace.
*
* @param mixed ...$values
*/
function trap(mixed ...$values): void
function trap(mixed ...$values): TrapHandle
{
if (!\class_exists(VarDumper::class)) {
throw new \RuntimeException('VarDumper is not installed. Please install symfony/var-dumper package.');
}

// Set default values if not set
if (!isset($_SERVER['VAR_DUMPER_FORMAT'], $_SERVER['VAR_DUMPER_SERVER'])) {
$_SERVER['VAR_DUMPER_FORMAT'] = 'server';
// todo use the config file in the future
$_SERVER['VAR_DUMPER_SERVER'] = '127.0.0.1:9912';
}

// If there are no values - stack trace
if ($values === []) {
// VarDumper::dump(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
$cwd = \getcwd();
$stack = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// Replace paths with relative paths
foreach ($stack as $i => $frame) {
if (isset($frame['file'])) {
$stack[$i]['file'] = \str_replace($cwd, '.', $frame['file']);
}
}
VarDumper::dump([
'cwd' => $cwd,
'trace' => new TraceStub($stack)
]);
return;
}

// Dump single value
if (\array_keys($values) === [0]) {
VarDumper::dump($values[0]);
return;
}

// Dump sequence of values
foreach ($values as $key => $value) {
/** @psalm-suppress TooManyArguments */
VarDumper::dump($value, $key);
}
return TrapHandle::fromArray($values);
}
} catch (\Throwable $e) {
// do nothing
}

/**
Expand Down

0 comments on commit 5097ee1

Please sign in to comment.