Skip to content

fix: coerce undefined values like null when serializing - #893

Open
cpruijsen wants to merge 2 commits into
fastify:mainfrom
cpruijsen:fix/issue-680-62de8a0f
Open

cpruijsen wants to merge 2 commits into
fastify:mainfrom
cpruijsen:fix/issue-680-62de8a0f

Conversation

@cpruijsen

Copy link
Copy Markdown

Fixes #680

Summary

Serialize undefined the same way as null: coerce it to the falsy value of the declared type instead of throwing. The reported case is ['test1', 'test2', 'test3', undefined] with items: { type: 'string' }, which threw TypeError: Cannot read properties of undefined (reading 'toString'). Objects, integer, number and the date formats threw in the same positions.

Each === null coercion guard in the generated code in index.js is now == null. In lib/serializer.js, asInteger and asNumber get a nullish early return, and the date serializers use == null. This follows the review of #681: "all functions need to conform to this behavior (nullish values get coerced to the falsy value of the corresponding type)".

Unchanged:

  • Object properties set to undefined are still skipped, as in JSON.stringify({ a: undefined }). A required property set to undefined still throws.
  • anyOf / oneOf still throw the schema mismatch for undefined, because no branch can be chosen.
  • format: 'unsafe'.

One output change for input that did not throw before: a nullable: true object schema with no properties now gives null for undefined instead of {}, the same as for null.

The alternative is to emit null for undefined array items, as JSON.stringify([undefined]) does. I did not take it because this library already coerces null to the type's falsy value, and #681 settled on one rule for both. The README "Nullable" section only describes null. I can add undefined there if you want it documented.

The new tests in test/missing-values.test.js fail without the source change and pass with it, except the cases that pin existing behaviour.

Checklist

Values set to undefined previously crashed the generated serializer
with a TypeError (e.g. Cannot read properties of undefined (reading
'toString')) for string and object types, or threw a conversion error
for integer, number and date-time formats.

Every position that already coerces null to the falsy value of the
declared type now treats undefined identically: "" for strings and
the date/date-time/time formats, 0 for integer and number, {} for
object, [] for array, false for boolean (unchanged), and null for
nullable and null-typed positions. Object properties set to undefined
are still skipped.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When asString receives undefined an exception is thrown

1 participant