Skip to content

Public request-level failure report for the server error hook (kind: "request") #3723

Description

@ryansolid

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions