refactor(server): dedupe HTTP error response builders - #1087
Merged
james-elicx merged 2 commits intoMay 5, 2026
Merged
Conversation
james-elicx
force-pushed
the
refactor/dedupe-http-error-responses
branch
from
May 5, 2026 19:22
650786f to
564ffc8
Compare
commit: |
Member
Author
|
/bigbonk review |
Contributor
There was a problem hiding this comment.
Clean refactor. Reviewed all 16 files — the extraction is mechanically correct and well-scoped.
What I checked:
forbiddenResponsemove fromrequest-pipeline.tstohttp-error-responses.ts— no external consumers imported it from the old location (index.tsanddeploy.tsonly import other symbols fromrequest-pipeline). The import inrequest-pipeline.tsitself is updated correctly.methodNotAllowedResponseinapp-page-method.ts— the old code createdHeaders, merged middleware headers, setAllow, then passed tonew Response. The new code createsHeaders, merges middleware headers, passes tomethodNotAllowedResponsewhich wraps innew Headers(init.headers)and setsAllow. One extraHeaderscopy but semantically identical.notFoundResponsevariable rename torenderedNotFoundResponseinapp-rsc-handler.ts— necessary to avoid shadowing the imported helper. Clean.internalServerErrorResponse(message)usage inapp-server-action-execution.ts— theundefinedfor production correctly falls back to the??default. Both call sites are consistent.- Body string changes (
"404 Not Found"→"Not Found") — confirmed no tests assert on the old body strings. Template-string sites indeploy.tsare left unchanged as documented. dev-origin-check.tskeeps its inlinenew Response("Forbidden", ...)— correctly listed as intentionally-inline.- No remaining canonical-body
new Response(...)calls outsidehttp-error-responses.tsanddev-origin-check.ts.
Nothing to flag. Good to merge.
Contributor
|
Review submitted — approved with detailed verification notes. The refactor is mechanically correct: all 16 files are consistent, the |
Extract notFoundResponse / badRequestResponse / internalServerErrorResponse / methodNotAllowedResponse into a shared http-error-responses.ts helper, alongside the existing forbiddenResponse (moved from request-pipeline.ts) and payloadTooLargeResponse (moved from app-server-action-execution.ts). Sites with custom bodies (e.g. "404 - API route not found", "Image not found", "missing pattern", "Page has no default export") and template-string-embedded sites in deploy.ts / pages-server-entry.ts / dev-origin-check.ts are left inline. Follow-up to cloudflare#1058. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
james-elicx
force-pushed
the
refactor/dedupe-http-error-responses
branch
from
May 5, 2026 19:30
564ffc8 to
241a869
Compare
james-elicx
marked this pull request as ready for review
May 5, 2026 19:30
james-elicx
enabled auto-merge (squash)
May 5, 2026 19:30
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.
Summary
Follow-up to #1058 / #1071 / #1078. Extracts a fresh batch of
new Response(...)HTTP error builders into a shared module,packages/vinext/src/server/http-error-responses.ts. Now home to:badRequestResponse(init?)— 400 "Bad Request"forbiddenResponse()— 403 "Forbidden" (moved fromrequest-pipeline.ts)notFoundResponse(init?)— 404 "Not Found"methodNotAllowedResponse(allowedMethods, init?)— 405 "Method Not Allowed" withAllowheaderpayloadTooLargeResponse()— 413 "Payload Too Large" (moved fromapp-server-action-execution.ts)internalServerErrorResponse(message?, init?)— 500 "Internal Server Error"Each helper accepts an optional
headersinit so callers (e.g.app-rsc-handler,app-page-method,prod-server) can merge middleware response headers without re-implementing thenew Response(...)boilerplate.Standardized status codes / sites touched
app-page-request.ts(×2) —validateAppPageDynamicParamsapp-prerender-endpoints.ts(×2) — disabled prerender endpointsapp-rsc-handler.ts— plain 404 fallback (with merged middleware headers)app-rsc-request-normalization.ts— basePath missapp-router-entry.ts(×2) — protocol-relative guard, null resultapp-ssr-entry.ts(×2) — protocol-relative guard, null resultmetadata-route-response.ts(×5) — sitemap/image/dynamic 404sprod-server.ts— Node static-served 404 (with merged static headers)request-pipeline.ts(×2) —guardProtocolRelativeUrl,normalizeTrailingSlashapp-router-entry.ts,app-rsc-request-normalization.ts,image-optimization.ts,middleware-runtime.tsAllow: GET, HEAD)app-page-method.tsapp-middleware.ts,pages-api-route.tsmiddleware-runtime.ts(dev-mode dynamic message viainternalServerErrorResponse(message))app-server-action-execution.ts(×2; prod = canonical, dev = "Server action failed: ..." viainternalServerErrorResponse(message))payloadTooLargeResponseis now the shared symbol)Body string changes (intentional, called out)
Five sites that previously returned the body
"404 Not Found"(the protocol-relative open-redirect guards inrequest-pipeline.ts×2,app-router-entry.ts,app-ssr-entry.ts, plus the trailing-slash defense-in-depth check) now return the canonical"Not Found"body. Status code (404) and absence ofContent-Typeare unchanged. The sibling generated-worker template strings indeploy.tskeep the old body to avoid touching codegen output.Sites left inline (intentional)
deploy.ts,entries/pages-server-entry.ts,server/dev-origin-check.ts.pages-api-route.ts:47andprod-server.ts:1593keep"404 - API route not found"(asserted intests/pages-api-route.test.ts:148);pages-api-route.ts:53keeps"API route does not export a default function".app-page-dispatch.ts:303("Page has no default export");pages-page-data.ts:139("404");image-optimization.ts(×4:"Image not found","The requested resource is not an allowed image type");app-prerender-endpoints.ts(×2:"missing pattern");request-pipeline.ts(image-URL validation custom bodies).app-route-handler-dispatch.ts(new Response(null, { status: 400 / 405 })),app-route-handler-execution.ts(status: 500with null body) — different shape from text-body helpers.config-matchers.ts(proxy gateway responses).Test plan
pnpm vp test run tests/app-router.test.ts— 308 passedpnpm vp test run tests/pages-router.test.ts— 200 tests pass (pre-existing afterAll cleanup hook timeout, unrelated to this change; verified by stashing the diff and reproducing on main)pnpm vp test run tests/app-rsc-handler.test.ts tests/app-prerender-endpoints.test.ts tests/app-page-request.test.ts tests/pages-api-route.test.ts tests/api-handler.test.ts tests/app-page-dispatch.test.ts tests/metadata-route-response.test.ts tests/app-page-route-wiring.test.ts tests/app-page-execution.test.ts tests/app-route-handler-policy.test.ts tests/image-optimization-parity.test.ts tests/image-config.test.ts tests/app-post-middleware-context.test.ts— 230 passedpnpm fmt --writepnpm knip— clean🤖 Generated with Claude Code