fix(error): don't throw on unparsable Host header in default error handlers - #4640
nikolas-sapa wants to merge 1 commit into
Conversation
…ndlers The default error handlers build the request URL from the raw Host header via `getRequestURL`. For a header that `new URL()` cannot parse (e.g. `Host: a b`), that call throws inside the handler itself, and the throw escapes as an unhandled rejection: every such request logs a full stack trace and the client receives a reduced body instead of the proper error payload. Add `getRequestURLOrFallback` and use it in both the production and dev handlers: on an unparsable authority it falls back to a synthetic `http://localhost` base, preserving path and query so the 404 redirect logic, the log line and the response body keep working. Valid Host and x-forwarded-host values are resolved exactly as before. Fixes nitrojs#4555
|
@nikolas-sapa is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
🔗 Linked issue
Resolves #4555
❓ Type of change
📚 Description
The default error handlers build the request URL from the raw
Hostheader viagetRequestURL(event, { xForwardedHost: true, xForwardedProto: true }). For a header thatnew URL()cannot parse —Host: a bfrom the issue's reproduction — that call throws inside the error handler itself, and the throw escapes as an unhandled rejection: every such request logs a full stack trace throughtrapUnhandledNodeErrorsand the client receives a reduced body instead of the proper error payload. TheHostheader is unvalidated input, so this is reachable by anyone withcurl -H 'Host: a b'.Both handlers are affected identically (
src/runtime/internal/error/prod.tsanddev.ts), so the fix adds one shared helper,getRequestURLOrFallback, ininternal/error/utils.ts: it resolves the URL exactly as before, and on an unparsable authority falls back to a synthetichttp://localhostbase while preserving path and query. That keeps all three URL consumers working in the degraded case — the 404 baseURL redirect logic (pathname/search), the[request error]log line, and the response body'surlfield.For every request with a valid
Hostorx-forwarded-host, behaviour is byte-identical to before; the handler only diverges where it previously threw.Testing.
test/unit/error-handler.test.tscovers: valid Host (unchanged URL), the malformed-Host degradation (no throw, fallback authority, status intact), path+query preservation, x-forwarded-host precedence (also unchanged), and the dev handler. Reverting the source change turns the three degradation tests red — the handler throwsTypeError [ERR_INVALID_URL]before reaching a response — while the two valid-header tests stay green either way.test/unitpasses (46 tests, including the pre-existing files), andtsc --noEmit/ eslint / prettier are clean.📝 Checklist