Skip to content

Commit

Permalink
fix: Exception message when an error happens for one of the ArrayMapp…
Browse files Browse the repository at this point in the history
…er elements
  • Loading branch information
autaut03 committed Oct 19, 2023
1 parent d6c65c4 commit d78ae82
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace GoodPhp\Serialization\TypeAdapter\Exception;

use Exception;
use GoodPhp\Serialization\TypeAdapter\Primitive\ClassProperties\Property\BoundClassProperty;
use GoodPhp\Serialization\TypeAdapter\Primitive\ClassProperties\PropertyMappingException;
use RuntimeException;
use Throwable;

Expand All @@ -13,4 +16,17 @@ public function __construct(
) {
parent::__construct("Could not map item at key '{$key}': {$previous->getMessage()}", 0, $previous);
}

public static function rethrow(int|string $key, callable $callback): mixed
{
try {
return $callback();
} catch (PropertyMappingException $e) {
throw new self($key . '.' . $e->path, $e->getPrevious());
} catch (CollectionItemMappingException $e) {
throw new self($key . '.' . $e->key, $e->getPrevious());
} catch (Exception $e) {
throw new self($key, $e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ public function to(array $value, Type $type, Serializer $serializer): array
{
$itemAdapter = $serializer->adapter(PrimitiveTypeAdapter::class, $type->arguments[1]);

return MultipleMappingException::map($value, false, function (mixed $item, string|int $key) use ($itemAdapter) {
try {
return $itemAdapter->serialize($item);
} catch (Exception $e) {
throw new CollectionItemMappingException($key, $e);
}
});
return MultipleMappingException::map(
$value,
false,
fn (mixed $item, string|int $key) => CollectionItemMappingException::rethrow(
$key,
fn () => $itemAdapter->serialize($item)
)
);
}

/**
Expand All @@ -46,12 +47,13 @@ public function from(array $value, Type $type, Serializer $serializer): array
{
$itemAdapter = $serializer->adapter(PrimitiveTypeAdapter::class, $type->arguments[1]);

return MultipleMappingException::map($value, false, function (mixed $item, string|int $key) use ($itemAdapter) {
try {
return $itemAdapter->deserialize($item);
} catch (Exception $e) {
throw new CollectionItemMappingException($key, $e);
}
});
return MultipleMappingException::map(
$value,
false,
fn (mixed $item, string|int $key) => CollectionItemMappingException::rethrow(
$key,
fn () => $itemAdapter->deserialize($item)
)
);
}
}
6 changes: 6 additions & 0 deletions tests/Integration/JsonSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,5 +496,11 @@ public function deserializesWithAnExceptionProvider(): Generator
),
'{"primitive":1,"nested":{"Field":123},"date":"2020-01-01T00:00:00.000+00:00","nullable":null,"carbonImmutable":"2020-01-01T00:00:00.000000Z"}',
];

yield 'ClassStub with wrong nested array field type' => [
new PropertyMappingException('date.0.Field', new UnexpectedTypeException(123, PrimitiveType::string())),
NamedType::wrap(ClassStub::class, [PrimitiveType::array(NestedStub::class)]),
'{"primitive":1,"nested":{"Field":"something"},"date":[{"Field":123}],"nullable":null,"carbonImmutable":"2020-01-01T00:00:00.000000Z"}',
];
}
}

0 comments on commit d78ae82

Please sign in to comment.