fix(serializer): preserve deserialization path and expected type on IRI type-confusion guard#8353
Conversation
…RI type-confusion guard The type-confusion guard in AbstractItemNormalizer::getResourceFromIri() threw a bare NotNormalizableValueException, dropping the deserialization path and expected type. With COLLECT_DENORMALIZATION_ERRORS enabled, DeserializeProvider::createViolationFromException() then produced an empty "This value should be of type ." violation with no property path (regression from api-platform#8333 vs 4.3.13). Build the exception through createForUnexpectedDataType() so the path and expected type are preserved, while keeping it a NotNormalizableValueException so union/intersection denormalization still falls through to the next member. Closes api-platform#8352 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2715c78704
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…guard For a union/intersection relation the guard now derives the expected types from the declared relation type (context['relation_native_type']) instead of reporting only the single class currently being attempted, so the restored validation metadata is accurate for union relations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Heads-up on CI: the failing jobs (PHPUnit (PHP 8.3) (Symfony lowest), PHPUnit api-platform/serializer (PHP 8.5 lowest)) are pre-existing on
On |
|
Thanks! |
Problem
The type-confusion guard in
AbstractItemNormalizer::getResourceFromIri()throws a bareNotNormalizableValueException, which carries neither the deserialization path nor the expected type:When
COLLECT_DENORMALIZATION_ERRORSis enabled (the default forDeserializeProvider),DeserializeProvider::createViolationFromException()then builds aConstraintViolationwith an empty property path and an empty expected type, so the user-facing violation degrades toThis value should be of type .with no property name.Before #8333 the guard threw an
InvalidArgumentException, which was caught a few lines below and re-thrown viaNotNormalizableValueException::createForUnexpectedDataType(...)— preserving both the path and the expected type. #8333 changed the throw to aNotNormalizableValueException(so union/intersection denormalization can fall through to the next member) but stopped going through the factory, dropping that metadata for the single-type case. This is a regression vs 4.3.13.POST a valid IRI that points to a resource of the wrong type for a relation:
propertyPath: "printingHouse",Invalid IRI "/publishing-houses/1".propertyPath: "",This value should be of type .Fix
Keep the exception a
NotNormalizableValueException(so the union/intersection fallback from #8333 / #8339 still works), but build it throughcreateForUnexpectedDataType()so the deserialization path and expected type are preserved on the resulting violation.Tests
AbstractItemNormalizerTest::testTypeConfusionGuardPreservesPathAndExpectedType— denormalizes a wrong-type IRI and asserts the thrownNotNormalizableValueExceptionkeeps its message, path and expected type. FullAbstractItemNormalizerTestsuite green (46 tests), including thetestUnionType*fallback tests from fix(serializer): fix union types denormalization fallback after security mismatch #8333 / fix(serializer): accept union-typed IRI collections on denormalization #8339.