Summary
configureServerErrors promises the ambient hook hears "the failure that fails a request", but the runtime can only report failures it meets itself — inside renderToStream (kind: "render") or inside a server-function dispatch (kind: "server-function"). A failure that happens in the framework's request handler before any render exists (Start middleware, setup, the render-mode module throwing) has no site and no public way to be reported. The only funnel is reportServerError, which is solid-js/internal.
Where this bites
solidjs/solid-vite-plugin#383 (design in solidjs/solid-vite-plugin#382) adds containment at the generated Start handler edge: a thrown Response becomes the response, anything else becomes a 500 instead of rejecting out to the host (Vite overlay / plain-text 500 / e.message echoed by the example server / configureServerErrors never hearing it). To report the failure it has to:
- import
reportServerError from solid-js/internal into every production Start build (the header says "NOT public API… may change or vanish in any release");
- read
globalThis[Symbol.for("solid-js/server/errors")].hook to decide whether to console.error — duplicating failRender's fallback policy (packages/web/src/server.ts ~L2061–2069);
- label the site
{ kind: "render", handling: "failed" } because ServerErrorSite.kind has nothing else. A monitor using the documented `solid.${kind}.${handling}` mechanism files middleware throws as render failures.
Proposal
Public request-level failure report on @solidjs/web/server, same policy as failRender, written once in the package that owns the slot:
// ServerErrorSite
kind: "render" | "server-function" | "request";
// handling for "request" is always "failed"; `event` always present.
export function reportRequestFailure(error: unknown, event: RequestEvent): void;
// = reportServerError(error, { kind: "request", handling: "failed", event }, null)
// + console.error(error) iff no ambient hook (per-request hooks don't exist at this layer)
Hook return ignored, as for every handling: "failed". The once-per-error ledger already applies, so an in-process server-function failure reported as server-function/thrown that then propagates through the middleware is not reported twice.
No change to renderToStream, onError, the server-function handler, or any wire format. configureServerErrors docs updated so "the failure that fails a request" is true for the pre-render case too.
Public API
ServerErrorSite.kind gains "request".
- New export
reportRequestFailure(error, event) from @solidjs/web/server.
Related, found while reviewing #383 (separate issues if you want them tracked)
- An async render failure before the shell with no boundary leaves the response pending forever (
createSSRResponse.end() never resolves the head).
- A framework-side throw after
next() has already returned a rendered page cannot cancel that render's stream; it keeps running into a buffer nobody reads.
Once this ships (rc.14), #383 shrinks to one import + one call; the containment shape and its fixtures stay as written.
— Claude via Cursor
Summary
configureServerErrorspromises the ambient hook hears "the failure that fails a request", but the runtime can only report failures it meets itself — insiderenderToStream(kind: "render") or inside a server-function dispatch (kind: "server-function"). A failure that happens in the framework's request handler before any render exists (Start middleware,setup, the render-mode module throwing) has no site and no public way to be reported. The only funnel isreportServerError, which issolid-js/internal.Where this bites
solidjs/solid-vite-plugin#383 (design in solidjs/solid-vite-plugin#382) adds containment at the generated Start handler edge: a thrown
Responsebecomes the response, anything else becomes a 500 instead of rejecting out to the host (Vite overlay / plain-text 500 /e.messageechoed by the example server /configureServerErrorsnever hearing it). To report the failure it has to:reportServerErrorfromsolid-js/internalinto every production Start build (the header says "NOT public API… may change or vanish in any release");globalThis[Symbol.for("solid-js/server/errors")].hookto decide whether toconsole.error— duplicatingfailRender's fallback policy (packages/web/src/server.ts~L2061–2069);{ kind: "render", handling: "failed" }becauseServerErrorSite.kindhas nothing else. A monitor using the documented`solid.${kind}.${handling}`mechanism files middleware throws as render failures.Proposal
Public request-level failure report on
@solidjs/web/server, same policy asfailRender, written once in the package that owns the slot:Hook return ignored, as for every
handling: "failed". The once-per-error ledger already applies, so an in-process server-function failure reported asserver-function/thrownthat then propagates through the middleware is not reported twice.No change to
renderToStream,onError, the server-function handler, or any wire format.configureServerErrorsdocs updated so "the failure that fails a request" is true for the pre-render case too.Public API
ServerErrorSite.kindgains"request".reportRequestFailure(error, event)from@solidjs/web/server.Related, found while reviewing #383 (separate issues if you want them tracked)
createSSRResponse.end()never resolves the head).next()has already returned a rendered page cannot cancel that render's stream; it keeps running into a buffer nobody reads.Once this ships (rc.14), #383 shrinks to one import + one call; the containment shape and its fixtures stay as written.
— Claude via Cursor