Repository navigation
Conversation
A failing test: an error that an API route throws never reaches Nitro's `error` hook, because the handler answers it inside its own h3 app. A Nitro plugin in the test app names the error its `error` hook received in a response header, and the test checks that header. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
👷 Deploy request for solid-start-landing-page pending review.Visit the deploys page to approve it
|
🦋 Changeset detectedLatest commit: e8441f8 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 |
commit: |
2 tasks done
The handler answered every error it caught inside its own h3 app, so its `fetch` never rejected and the server hosting it never saw an error that an API route or middleware threw. With Nitro, the `error` hook, where error reporters capture server errors, and the `errorHandler` did not run for it; SolidStart's own dev server never reached its error overlay. A `fetch` call now rejects when a route, a middleware or the handler throws an error that h3 would answer as unhandled for the request passed to that call: with the thrown `Error`, or with an unhandled 500 caused by a thrown value that is not one, or by another library's error named `HTTPError`. An h3 `HTTPError` not marked unhandled, a status thrown as a number, or h3's not-found and handled markers are answered as before, and so is an error reached through `request()`, also during a `fetch` call; an h3 app the handler is mounted in, or one that enters it through its `handler`, gets the error, as before. Each call keeps its own state, so overlapping calls, also with one `Request`, do not mix their errors. The preview server answers a rejected `fetch` with a 500. Headers set for the error response with `event.res.errHeaders` are not part of the host's answer. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lxsmnsyc
approved these changes
Nov 11, 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.
PR Checklist
Please check if your PR fulfills the following requirements:
errorhook #2378What is the current behavior?
An error that an API route or a middleware throws never reaches Nitro's
errorhook or itserrorHandler, because the handler answers it inside its own h3 app and itsfetchnever rejects. The steps and the details are in #2378. In SolidStart 1.5.1 the same API route's error reached Nitro's error hook.What is the new behavior?
The first commit is the failing test, as in CONTRIBUTING's "Failing Test PR". The second commit is the proposed fix:
fetchrejects with it, so the server hosting the handler answers and reports it. With Nitro, that means theerrorhook, then theerrorHandler.HTTPErrornot marked unhandled, a status thrown as a number and h3's not-found and handled markers, by SolidStart; an error reached throughrequest(), by SolidStart; an error reached through an h3 app that the handler is mounted in, by that app.packages/start/src/server/handler.spec.tsis new,packages/start/src/config/dev-server.spec.tsgets a test of the preview server, and the e2e test of the first commit now passes. A patch changeset is included.Other information
This changes who answers an unhandled error:
fetchcan now reject, unlike h3'sH3.fetch. A server or adapter that calls it directly answers such an error itself.errorHandlerapplies; headers set for the error response withevent.res.errHeaderson SolidStart's event are not in the host's answer.#2378 has the full list of trade-offs (including the status and headers of the answer, which errors still do not reach the hook, server function requests that fail before the function runs) and two alternatives that keep SolidStart's answers (calling Nitro's
captureError, or an error option on the handler). The e2e test runs undervite dev; I also ran a production build of a new app with@solidjs/startpacked from this branch: theerrorhook gets the API route's error and Nitro answers the 500.I pushed the fix now, rather than waiting for an answer on the approach, so that the approach can be judged with the code. If you prefer one of the alternatives or another approach, I will change this pull request.