fix: serialize Date objects before Standard Schema validation#1690
fix: serialize Date objects before Standard Schema validation#1690raunak-rpm wants to merge 4 commits intoelysiajs:mainfrom
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughAdded a public Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Handler
participant Serializer as Serializer\n(serializeDates)
participant Validator
participant Encoder as Encoder/Response
Client->>Handler: send/return value (may contain Date)
Handler->>Serializer: serializeDates(value)
Serializer-->>Handler: value with Dates as ISO strings
Handler->>Validator: validate(serializedValue)
Validator-->>Handler: validation result
Handler->>Encoder: encode(serializedValue)
Encoder-->>Client: HTTP response (ISO strings)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/schema.ts`:
- Around line 387-405: serializeDates currently calls
Date.prototype.toISOString() which throws RangeError for invalid Dates; instead
detect invalid Date values inside serializeDates (the Date branch) by checking
Number.isNaN(date.getTime()) or similar and return null for invalid Dates to
match JSON.stringify behavior, leaving valid Dates serialized toISOString();
apply the same check when traversing nested structures via serializeDates so
invalid Date instances anywhere in arrays/objects produce null rather than
throwing.
This commit fixes an issue where response validation fails when using Standard Schema validators (Zod, Effect, etc.) with Date types. ## Problem When returning Date objects from handlers with Standard Schema response validation, the validation fails because: 1. Response validation (Check) happens BEFORE encoding 2. The schema expects a string (JSON representation) 3. But the Date object hasn't been serialized yet 4. JSON.stringify would convert Date to ISO string, but validation failed first ## Solution Added `serializeDates` helper function that recursively converts Date objects to ISO strings (matching JSON.stringify behavior). This function is now called BEFORE validation in all three Standard Schema validator code paths: - Dynamic async validators - Non-async validators (with sub-validators) - Non-async validators (without sub-validators) The Encode function also uses serializeDates to ensure proper transformation. Fixes elysiajs#1670
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/schema.ts`:
- Around line 387-403: serializeDates currently skips invoking toJSON(), causing
mismatches with JSON.stringify; update serializeDates (function name:
serializeDates) so that after handling Date instances you check whether the
value has a toJSON function (e.g. value && typeof (value as any).toJSON ===
'function') and, if so, call that toJSON() and pass its result back into
serializeDates (to handle nested serialization and maintain JSON.stringify
semantics) before proceeding to array/object traversal; ensure the recursive
call replaces the original value to avoid duplicating logic or missing
transformed primitives.
The serializeDates function now checks for toJSON method on objects before array/object traversal. This ensures proper JSON.stringify semantics where custom toJSON methods are called and their results are recursively processed. This fixes cases where objects with custom toJSON methods would be traversed as regular objects instead of having their toJSON result serialized. Changes: - Added toJSON check in serializeDates after Date handling - toJSON result is recursively passed through serializeDates - Added tests for toJSON handling with various return types
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/schema.ts`:
- Around line 656-669: Errors currently returns a Promise; change it to return
an iterable immediately by calling Check(serializeDates(value)) and returning
its .issues synchronously: implement Errors as something like const res =
Check(serializeDates(value)); if (res && typeof (res as any).then ===
'function') return []; return (res as { issues?: unknown[] }).issues ?? []; this
keeps the signature expected by callers (use of spread and .First()) while using
Check and serializeDates from the surrounding code.
🧹 Nitpick comments (1)
src/schema.ts (1)
892-902: Clarify:Decodedoes not serialize dates, unlikeCheck/Encode.
Decodevalidates the rawvaluewithout callingserializeDates, whileCheckandErrorsserialize dates before validation. This appears intentional (Decode is for input parsing, Check/Encode for output), but the asymmetry could cause confusion. Consider adding a brief comment explaining whyDecodeoperates on the raw value.📝 Suggested comment
// `@ts-ignore` Decode(value) { + // Decode operates on raw input values, not serialized output // `@ts-ignore` const response = schema['~standard'].validate(value)
Summary
This PR fixes an issue where response validation fails when using Standard Schema validators (Zod, Effect, Valibot, etc.) with Date types.
Fixes #1670
Problem
When returning Date objects from handlers with Standard Schema response validation, the validation fails with a 422 error:
The root cause is:
Check) happens before encodingJSON.stringifywould convert Date to ISO string, but validation fails firstThis was already fixed for TypeBox's
t.Date()in PR #1327, but not for Standard Schema validators.Solution
Added a
serializeDateshelper function that recursively converts Date objects to ISO strings (matchingJSON.stringifybehavior). This function is now called before validation in all three Standard Schema validator code paths:The
Encodefunction also usesserializeDatesto ensure proper transformation.Changes
serializeDateshelper and updated all Standard Schema validators to serialize dates before validationTesting
All 1455 tests pass, including 8 new tests for date serialization:
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.