Repository navigation
Conversation
|
Can you plz fix the lint error? |
There was a problem hiding this comment.
Pull request overview
This PR updates Fastify’s TypeScript types to allow reply.send() to accept PromiseLike<T> payloads and adds type-level tests asserting the new behavior.
Changes:
- Widen
SendArgs<ReplyType>to includePromiseLike<ReplyType>in all branches (optional/required payload cases). - Add/adjust
tsdtests to validatereply.send(Promise.resolve(...))is accepted and wrong resolved types are rejected. - Add a note in the
SendArgsJSDoc claiming runtime support viawrap-thenable.js.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| types/type-provider.d.ts | Broadens SendArgs to allow PromiseLike payloads and updates comment explaining the rationale. |
| test/types/reply.test-d.ts | Updates tsd expectations and adds new type tests for reply.send() with Promise payloads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
@skdas20 would you like to finalize this PR? |
77d8eb5 to
badaa91
Compare
|
Force-pushed a rebase + fix for the issues raised here:
All type tests ( |
|
Thanks @Eomm — added all four, plus one more that writing them turned up. Behaviour of the four cases (all now asserted):
Case 4 is worth a maintainer opinion: with promise payloads the winner is whichever settles first, not whichever The extra fix: case 3/4 exposed that when Full unit suite green locally (2064 passing), lint clean. Happy to split the unhandled-rejection fix into its own PR if you'd rather keep this one narrow. |
|
@skdas20 As soon as you have time, can you resolve conflicts? |
Widens SendArgs so send() accepts a PromiseLike<ReplyType>, and adds the matching runtime support in Reply.prototype.send(): a thenable payload is now resolved (reusing the existing wrap-thenable path used for handler return values) and its value sent, or its rejection reason sent as an error. Previously the type-only version of this change would have shipped a type that didn't match runtime behavior: calling send() with a Promise would have just serialized the Promise object itself. Flagged in review by Copilot on the original PR. Resolves merge conflicts and lint/CI failures from the original branch, and updates the other type tests (type-provider, instance) whose expected send() signatures were widened by this change. Signed-off-by: Sumit Kumar Das <[email protected]>
Adds the cases @Eomm asked for: returning reply.send(promise) from a sync handler, reply.send(promise) inside an async handler, and calling send() twice with promises (both already-resolved and settling out of order). Writing them surfaced a real hazard: when send() bails because the reply was already sent, a thenable payload was dropped without any handler attached, so an eventual rejection became an unhandled rejection (fatal by default on modern Node). It now attaches a handler that logs it. Signed-off-by: skdas20 <[email protected]>
bdaecef to
e35ddb1
Compare
|
@Tony133 done — rebased onto The only conflict was in Green locally after the rebase: 89 unit tests in @Eomm the question from my earlier comment is still open whenever you have a moment: with two promise payloads, the one that settles first wins rather than the one |
|
Can you change the PR description? This is a full implementation of that feature. I'm not exactly sure we should land this, because what this wants to achieve is already supported with a slightly different API: return the thenable from the handler. Why adding it? |
|
Description rewritten — it described the original types-only diff, which was stale. It now states plainly that this is a feature implementation plus a separable robustness fix. On whether it should land: your instinct is right, and I don't have a user-facing justification to offer. There is no linked issue and no reported problem behind this PR. It began as a types-only widening, and the runtime work exists only because that widened type would otherwise have described behaviour Since
I'd suggest (2). Happy to open it as a separate PR against a clean branch and close this one — just say the word rather than my assuming. |
|
@mcollina I've opened #6936 with just the unhandled-rejection half — option (2) from my previous comment. It's four lines plus a test and doesn't touch Leaving this PR open for now in case you want the feature, but I have no attachment to it — if your answer is that |
What this does
Two things, which are separable:
1. Makes
reply.send(promise)actually work at runtime.SendArgsis widened to acceptPromiseLike<ReplyType>, andReply.prototype.sendroutes a thenable payload through the existingwrap-thenablepath instead of serializing the promise object itself.2. Stops a dropped thenable from crashing the process. When
send()bails out through thethis.sent === truebranch, the payload is discarded. If that payload is a promise that later rejects, nothing has attached a handler to it, so it surfaces as an unhandled rejection — fatal by default on modern Node.send()now attaches a handler that logs it instead. This one is a robustness fix that applies regardless of whether (1) is wanted, since a JS user can pass a promise today whether or not the types permit it.Behaviour
reply.send(Promise.resolve(x))sendsx; a rejection is sent through the error path.send()was called for first — the payload isn't known until settlement. Asserted explicitly incalling reply.send(promise) twice is settle-ordered, not call-ordered, since it differs from the plain-value case.Tests
test/internals/reply.test.jscovers resolve, reject,return reply.send(promise)from a sync handler,send()inside an async handler, double-send with already-resolved promises, double-send settling out of order, and the dropped-rejection case. Type tests updated inreply.tst.ts,type-provider.tst.ts,instance.tst.ts.Locally: 89 unit tests in
reply.test.js, tstyche 1284 assertions across 16 files, lint clean.Status
Opened originally as a types-only change. It grew into the above because the widened type would otherwise have described behaviour the runtime did not implement. See the discussion below on whether the feature is wanted at all.