Repository navigation
feat!: Report a server-initiated stream close to the error handler - #91
Merged
Merged
Conversation
When the server ends the stream and close was not called, on_error now gets an SSE::Errors::StreamClosedError. The client reconnects as before. This follows the WHATWG SSE processing model, where a normal end of body fires error before it reestablishes the connection. BREAKING CHANGE: A caller that calls close on any error now stops reconnecting after a server close.
jsonbailey
marked this pull request as ready for review
September 25, 2026 20:06
tanderson-ld
approved these changes
Sep 25, 2026
2 of 3 tasks
jsonbailey
pushed a commit
that referenced
this pull request
Sep 28, 2026
🤖 I have created a release *beep* *boop* --- ## [3.0.0](2.6.0...3.0.0) (2026-09-28) ### ⚠ BREAKING CHANGES * Report a server-initiated stream close to the error handler ([#91](#91)) ### Features * Report a server-initiated stream close to the error handler ([#91](#91)) ([7e4dc1b](7e4dc1b)) ### Bug Fixes * Declare logger as a runtime dependency ([#94](#94)) ([f7809c2](f7809c2)) * Stop the worker thread promptly when the client is closed during a reconnect wait ([#93](#93)) ([054b11b](054b11b)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > **Release 3.0.0** — bumps the package version from `2.6.0` to `3.0.0` in `.release-please-manifest.json`, `lib/ld-eventsource/version.rb`, and documents the release in `CHANGELOG.md`. > > This is a Release Please cut, not new library logic in the diff. The changelog records what ships in **3.0.0**: a **breaking** behavior change where a **server-initiated stream close** is reported through the client **error handler** (e.g. `StreamClosedByServerError`), plus fixes to declare **`logger` as a runtime dependency** and to **stop the worker thread promptly** when the client is closed during a reconnect backoff wait. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d5431c5. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.
Summary
When the server ends the stream and
closewas not called, the client now passes anSSE::Errors::StreamClosedByServerErrortoon_error. The client then reconnects as before.This follows the WHATWG SSE processing model. On a normal end of body, the client must "reestablish the connection", and that step fires the
errorevent. The Go, Java and Python eventsource libraries already report a server close to the error handler. Before this change, the Ruby gem reconnected silently.Why now
The Ruby server SDK's RETRY conformance work (SDK-2793) controls the reconnect delay and waits in its error handler. It needs this signal. Without it, a server close reconnects with no delay.
Breaking change
A caller that calls
closeon any error now stops reconnecting after a server close. Release as 3.0.0.Testing
bundle exec rspec spec: 171 examples, 0 failures.bundle exec rubocop --parallel: 16 files inspected, no offenses.03c7b1a, with long-running tests enabled: 4697 tests ran, 0 failed.Jira
SDK-3204
Note
Overview
Breaking: When the server ends the SSE body (EOF or
nilfromreadpartial), the client now raisesSSE::Errors::StreamClosedByServerErrorand delivers it toon_errorbefore reconnecting, instead of exiting the read loop silently. Aligns with WHATWG SSE and other LaunchDarkly eventsource clients so callers can apply reconnect delay in the error handler.ReadTimeoutErroris unchanged and is not conflated with server close. Client-initiatedclosestill avoids surfacing an error toon_error.New specs cover EOF/nil paths, timeout vs close, no error on client close, and reconnect when the error handler raises.
headers_specuses the sharedsend_stream_contenthelper.Reviewed by Cursor Bugbot for commit 03536d4. Bugbot is set up for automated code reviews on this repo. Configure here.