fix: don't mask errors with a "header is already set" error when rendering the error page - #16323
fix: don't mask errors with a "header is already set" error when rendering the error page#16323Nic-Polumeyv wants to merge 3 commits into
Conversation
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/097ae7d6c082db46ca16a4d59410ac35a16f4fa9Open in Note This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed. |
🦋 Changeset detectedLatest commit: 097ae7d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
5767856 to
037aa33
Compare
|
Since #16664 this masking got worse: the synthetic "header is already set" error reaches |
|
Looks like #11676 is fixed on v3, though the test in this PR still fails on I think the correct fix here is to roll back any headers (and |
037aa33 to
bbc87cf
Compare
If the root layout
loadcallssetHeadersand something throws after the page rendered, the error page dies too.respond_with_errorre-runs the root layoutloadon the same event, so the secondsetHeaderscall hits the set-once check and throws"cache-control" header is already set. That error replaces the real one inhandle_error_and_jsonify, so the log shows only thesetHeaderscomplaint and the response falls back to the static error page instead of+error.svelte.The set-once throw is by design (#5778) and stays untouched. Instead,
resolvesnapshots the headershandlehas set before any route logic runs, andrespond_with_errorrestores that snapshot before rendering, so the error page starts from the post-handlestate and the re-run root layoutloadsets its headers on a clean slate. Headers the failed render set for the page that never shipped are dropped rather than leaked onto the error response, andserver-timingno longer doubles up during the re-run.localsand cookies are deliberately left alone, a shallow copy can't undo mutations to nested state and rolling back a session cookie on an error page would log people out.Finding a trigger takes more care here than on kit 2.
loaderrors take the nearest-boundary path without re-running the root layout, and onversion-3render errors are caught in place by the root<svelte:boundary>too, so neither reachesrespond_with_erroranymore. Anything that throws after the loads settled still does,transformPageChunkin the tests' case, and so does a page module that fails to import (the trigger in the original issue).Fixes #11676