Repository navigation
Keep handler errors from claiming the reserved SERVER_DRAINING code - #434
Merged
Merged
Conversation
Only the runtime admission refusal may carry SERVER_DRAINING, so a procedure that already ran is never resent. Remap a handler-returned SERVER_DRAINING to UNCAUGHT_ERROR and log a warning. Assisted-by: Replit
darshkpatel
approved these changes
Oct 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
resendRefusedCallsresends an RPC when its result carriesSERVER_DRAINING, because that code means the server refused the call before middleware or handlers ran. A procedure whose error schema includesReaderErrorSchemaor the literal'SERVER_DRAINING'can return that code after it already ran. The client then resends work that has already happened.What changed
SERVER_DRAININGerror toUNCAUGHT_ERRORwith the same message and logs a warning. Only the runtime admission refusal can now sendSERVER_DRAINING.Versioning
No wire change or version bump. A handler that returned
SERVER_DRAININGnow has its error delivered asUNCAUGHT_ERROR. That code was reserved for the drain refusal in 0.226.0.Tests
npm run test:singleexited 0.npm run checkexited 0: TypeScript, Prettier, and ESLint passed.SERVER_DRAINING; the client hasresendRefusedCalls, and the test rotates the session. The procedure runs exactly once and the client receivesUNCAUGHT_ERROR.['claim', 'claim']) instead of once. The remap was restored.Appendix
Decisions
UNCAUGHT_ERROR, the existing built-in code for handler failures, and keep the handler message. A warning log matches the existing handler-error logging.Facts verified in code
router/client.ts:336: resend is keyed only onresult.payload.code === SERVER_DRAINING_CODE.router/server.ts:606-633: the handler result writer, now with the remap.router/server.ts:242-254: the runtime refusal is sent viacancelStream, not the result writer.router/server.ts:662-686: the existingUNCAUGHT_ERROR_CODEprecedent for handler failures.Review dispositions
SERVER_DRAINING, and all existing drain tests pass. A handler error with any other code is unchanged. No new casts orany.~ written by ⠕ Replit