Skip to content

Commit

Permalink
misc: catch json_encode exception to help identifying parsing errors
Browse files Browse the repository at this point in the history
This brings two improvements:

- The reason for the JSON parsing failure is visible in the stack
  trace / `$previous` exception, allowing the developer to determine
  whether the parsing failure was caused by a syntax error, invalid
  UTF-8 sequence or something else.
- The JSON string null (which decodes to null) is no longer erroneously
  rejected as invalid. Instead it is rejected, because it is not
  iterable, slightly improving the error reporting.
  • Loading branch information
TimWolla committed Apr 24, 2023
1 parent 2290981 commit 861c3b9
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 9 deletions.
3 changes: 0 additions & 3 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
UnionTypesRector::class => [
__DIR__ . '/tests/Unit/Definition/Repository/Reflection/ReflectionClassDefinitionRepositoryTest',
],
JsonThrowOnErrorRector::class => [
__DIR__ . '/src/Mapper/Source/JsonSource.php',
],
MixedTypeRector::class => [
__DIR__ . '/tests/Integration/Mapping/Object/UnionValuesMappingTest.php',
__DIR__ . '/tests/Unit/Definition/Repository/Reflection/ReflectionClassDefinitionRepositoryTest',
Expand Down
6 changes: 4 additions & 2 deletions src/Mapper/Source/Exception/InvalidJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@

namespace CuyZ\Valinor\Mapper\Source\Exception;

use JsonException;
use RuntimeException;

/** @internal */
final class InvalidJson extends RuntimeException implements InvalidSource
{
public function __construct(private string $source)
public function __construct(private string $source, ?JsonException $previous = null)
{
parent::__construct(
'Invalid JSON source.',
1566307185
1566307185,
$previous
);
}

Expand Down
11 changes: 7 additions & 4 deletions src/Mapper/Source/JsonSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
use CuyZ\Valinor\Mapper\Source\Exception\SourceNotIterable;
use Iterator;
use IteratorAggregate;
use JsonException;
use Traversable;

use function is_iterable;
use function json_decode;

use const JSON_THROW_ON_ERROR;

/**
* @api
*
Expand All @@ -29,10 +32,10 @@ final class JsonSource implements IteratorAggregate
*/
public function __construct(string $jsonSource)
{
$source = json_decode($jsonSource, true);

if ($source === null) {
throw new InvalidJson($jsonSource);
try {
$source = json_decode($jsonSource, associative: true, flags: JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new InvalidJson($jsonSource, $e);
}

if (! is_iterable($source)) {
Expand Down

0 comments on commit 861c3b9

Please sign in to comment.