Skip to content

SSE: a generator that throws mid-stream hangs the response + uncaughtException (follow-up to #1628) #1763

Description

@kriszyp

Summary

Follow-up to #1628 (fixed by #1632, which handled a finite generator streamed to completion). A distinct code path on the same generator→SSE-terminal surface is still broken: a streaming Resource whose async generator throws partway through iteration over SSE (Accept: text/event-stream) logs an uncaughtException and the HTTP response never closes on its own — the client hangs indefinitely.

Repro / observation (harper main 31de6a3be)

A ThrowGen streaming Resource that yields 2 events then throws, consumed over SSE:

  • Node logs an uncaughtException originating from the internal nextAsync / Readable.from machinery.
  • The response is never terminated by the server. In the test harness only a 15s AbortController ended it (events=2, ended=false, aborted=true).

For contrast, in the same run every completing generator (empty / single / 5-event / 3000-event) closed cleanly with the exact event count and no uncaughtException — i.e. the #1628 fix is solid; this is purely the error path.

Exploratory-QA repro fixture is available (a ThrowGen Resource alongside FiniteGen/EmptyGen/SingleGen/LargeGen), and can be turned into a regression test once the fix lands.

Impact

  • Any app whose SSE-streamed generator can throw mid-iteration (a DB error mid-scan, an upstream/origin failure, or a bug in user generator code) leaves that client connection wedged open, plus an uncaughtException in the logs (noise + potential worker instability — a post-run liveness probe suggested the worker itself survives via a global handler, but the erroring request does not terminate).

Suggested direction

The SSE terminal/teardown path needs to treat a generator rejection the same way it now treats terminal {done:true} — surface the error to the response (or at least close the stream) rather than letting it escape as an uncaughtException with the connection left open.


Surfaced by the exploratory-QA loop while regression-verifying #1628. 🤖 Issue drafted by an LLM (KrAIs / Claude Opus 4.8); please sanity-check the root-cause framing before prioritizing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions