Skip to content

Commit

Permalink
improve flatten args in error context transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Jan 17, 2025
1 parent af130b0 commit 89af4c8
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 18 deletions.
5 changes: 5 additions & 0 deletions baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@
<code><![CDATA[iterable<SubscriberAccessor>]]></code>
</DeprecatedInterface>
</file>
<file src="src/Subscription/ThrowableToErrorContextTransformer.php">
<MixedAssignment>
<code><![CDATA[$value]]></code>
</MixedAssignment>
</file>
<file src="tests/Benchmark/PersonalDataBench.php">
<MissingConstructor>
<code><![CDATA[$multipleEventsId]]></code>
Expand Down
8 changes: 7 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ parameters:
path: src/Subscription/RetryStrategy/ClockBasedRetryStrategy.php

-
message: '#^Parameter \#3 \$errorContext of class Patchlevel\\EventSourcing\\Subscription\\SubscriptionError constructor expects list\<array\{class\: class\-string, message\: string, code\: int\|string, file\: string, line\: int, trace\: list\<array\{file\?\: string, line\?\: int, function\?\: string, class\?\: string, type\?\: string, args\?\: array\<mixed\>\}\>\}\>\|null, mixed given\.$#'
message: '#^Parameter \#3 \$errorContext of class Patchlevel\\EventSourcing\\Subscription\\SubscriptionError constructor expects list\<array\{namespace\: string, short_name\: string, class\: class\-string, message\: string, code\: int\|string, file\: string, line\: int, trace\: list\<array\{file\?\: string, line\?\: int, function\?\: string, class\?\: string, type\?\: string, args\?\: array\<mixed\>\}\>\}\>\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Subscription/Store/DoctrineSubscriptionStore.php
Expand All @@ -155,3 +155,9 @@ parameters:
identifier: trait.unused
count: 1
path: src/Subscription/Subscriber/SubscriberUtil.php

-
message: '#^Cannot cast mixed to string\.$#'
identifier: cast.string
count: 1
path: src/Subscription/ThrowableToErrorContextTransformer.php
2 changes: 1 addition & 1 deletion src/Subscription/SubscriptionError.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

/**
* @psalm-type Trace = array{file?: string, line?: int, function?: string, class?: string, type?: string, args?: array<array-key, mixed>}
* @psalm-type Context = array{class: class-string, message: string, code: int|string, file: string, line: int, trace: list<Trace>}
* @psalm-type Context = array{namespace: string, short_name: string, class: class-string, message: string, code: int|string, file: string, line: int, trace: list<Trace>}
*/
final class SubscriptionError
{
Expand Down
66 changes: 55 additions & 11 deletions src/Subscription/ThrowableToErrorContextTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@

use function array_key_exists;
use function array_map;
use function array_walk_recursive;
use function array_pop;
use function explode;
use function get_debug_type;
use function get_resource_type;
use function implode;
use function is_array;
use function is_bool;
use function is_float;
use function is_int;
use function is_object;
use function is_resource;
use function sprintf;

/**
* @psalm-import-type Context from SubscriptionError
Expand All @@ -39,7 +45,13 @@ private static function transformThrowable(Throwable $error): array
/** @var list<Trace> $traces */
$traces = $error->getTrace();

$classParts = explode('\\', $error::class);
$shortClass = array_pop($classParts);
$namespace = implode('\\', $classParts);

return [
'short_name' => $shortClass,
'namespace' => $namespace,
'class' => $error::class,
'message' => $error->getMessage(),
'code' => $error->getCode(),
Expand All @@ -60,18 +72,50 @@ private static function transformTrace(array $trace): array
return $trace;
}

array_walk_recursive($trace['args'], static function (mixed &$value): void {
if (is_object($value)) {
$value = sprintf('object(%s)', $value::class);
}
$trace['args'] = self::flattenArgs($trace['args']);

return $trace;
}

/**
* @param array<array-key, mixed> $args
*
* @return array<array-key, mixed>
*/
private static function flattenArgs(array $args, int $level = 0, int &$count = 0): array
{
$result = [];

foreach ($args as $key => $value) {
$count++;

if (!is_resource($value)) {
return;
if ($count > 10_000) {
return ['array', '*SKIPPED over 10000 entries*'];
}

$value = sprintf('resource(%s)', get_resource_type($value));
});
if (is_object($value)) {
$result[$key] = ['object', get_debug_type($value)];
} elseif (is_array($value)) {
if ($level > 10) {
$result[$key] = ['array', '*DEEP NESTED ARRAY*'];
} else {
$result[$key] = ['array', self::flattenArgs($value, $level + 1, $count)];
}
} elseif ($value === null) {
$result[$key] = ['null', null];
} elseif (is_bool($value)) {
$result[$key] = ['boolean', $value];
} elseif (is_int($value)) {
$result[$key] = ['integer', $value];
} elseif (is_float($value)) {
$result[$key] = ['float', $value];
} elseif (is_resource($value)) {
$result[$key] = ['resource', get_resource_type($value)];
} else {
$result[$key] = ['string', (string)$value];
}
}

return $trace;
return $result;
}
}
22 changes: 17 additions & 5 deletions tests/Unit/Subscription/ErrorContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,23 @@ public function testErrorContext(): void
$this->assertSame('->', $firstTrace['type'] ?? null);
$this->assertArrayHasKey('args', $firstTrace);
$this->assertSame([
'test',
'object(Patchlevel\EventSourcing\Aggregate\CustomId)',
'resource(stream)',
['test' => [1, 2, 3]],
'object(Closure)',
['string', 'test'],
['object', 'Patchlevel\EventSourcing\Aggregate\CustomId'],
['resource', 'stream'],
[
'array',
[
'test' => [
'array',
[
['integer', 1],
['integer', 2],
['integer', 3],
],
],
],
],
['object', 'Closure'],
], $firstTrace['args'] ?? null);
}

Expand Down

0 comments on commit 89af4c8

Please sign in to comment.