fix(core): Guard relation custom field resolution against a missing entity id - #5006
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughCustom field relation resolution now supports embedded value objects without an Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
I have read the CLA Document and I hereby sign the CLA |
30015e0 to
81b7a5e
Compare
grolmus
left a comment
There was a problem hiding this comment.
Thanks @brmk — clean, honest, well-scoped fix. Reviewed the diff, traced the root cause, and ran it locally.
Root cause confirmed: generate-resolvers.ts attaches [ENTITY_ID_KEY]: source.id to the custom-fields resolver value, and for an OrderAddress (an embedded value object with no id) that's undefined, which then reached loader.load(undefined). Guarding entityId == null and returning []/null is the right fix, in the right place:
- It sits after the eager-load short-circuit, so no id-bearing entity can wrongly hit the null branch.
== nullcorrectly matches only null/undefined (Vendure ids are never a falsy-but-valid0).- Returning null restores the documented pre-3.7 behaviour — the stored FK scalar (
singleId) isn't consulted by either resolution path even today (the DataLoader path joins the parent entity table by id, which an embedded object doesn't have), so null is the honest result here rather than something being silently dropped. - The type widening to
ID | undefinedis accurate and non-breaking (ResolveRelationConfigisn't part of the public API).
Testing: the new e2e reproduces the real crash path (set a shipping address with relation custom fields, then query them). Ran the full custom-field-relations suite locally — 62 passed.
Two optional, non-blocking follow-ups (no need to hold this PR):
- A one-line assertion on
customFields.primitivein the new test would confirm the guard doesn't collaterally affect scalar custom fields on the snapshot. - Actually resolving
OrderAddressrelation custom fields from the stored<name>Idscalar would be a nice future enhancement — it's a separate feature from this crash fix, so worth a follow-up issue if the team wants it.
Approving. 🚀
Description
Relation-type custom fields selected on an embedded value object with no database
id— the canonical case beingOrderAddress(Order.shippingAddress/billingAddress) — crash with:This is a regression from #4923 (perf(core): resolve relation custom fields using request-scoped DataLoader batching): relation custom fields are now resolved through a DataLoader keyed by the parent entity id. For an
OrderAddressthat id isundefined(it is a JSON snapshot with no entity id), soDataLoader.load(undefined)throws. It surfaces as a GraphQL error (HTTP 200 with anerrorsarray), so it is invisible in server logs and can silently break checkout flows that read the order's shipping/billing address. Before #4923 these relations resolved without DataLoader and returnednullon anOrderAddressrather than throwing.Fix
Guard the undefined
entityIdinCustomFieldRelationResolverService.resolveRelationand resolve tonull(or[]for a list field) — an embedded value object legitimately has no id.ResolveRelationConfig.entityIdis widened toID | undefinedto reflect what the single call site (generate-resolvers.ts,source[ENTITY_ID_KEY]) actually passes.Reproduction
relationcustom field onAddress(any target entity).setOrderShippingAddresswith the custom field set.activeOrder { shippingAddress { customFields { <relation> { id } } } }→ GraphQL error.Tests
Added an e2e regression test to
custom-field-relations.e2e-spec.ts(Address entitygroup) that drives the order shipping-address path. Verified locally:custom-field-relationse2e suite passes (62/62).The loader.load() function must be called with a value, but got: undefined.Fixes #5004
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.