Skip to content

fix: stream errors to client before breaking generator loop - #587

Open
Swigler wants to merge 1 commit into
runpod:mainfrom
Swigler:fix/stream-error-delivery
Open

fix: stream errors to client before breaking generator loop#587
Swigler wants to merge 1 commit into
runpod:mainfrom
Swigler:fix/stream-error-delivery

Conversation

@Swigler

@Swigler Swigler commented Sep 3, 2026

Copy link
Copy Markdown

Summary

  • Stream errors are now delivered to clientsstream_result() is called with the error before breaking out of the generator loop
  • Extra fields are preserved — fields like context and refresh_worker survive error extraction instead of being stripped

Fixes #397

What was wrong

Since v1.7.7 (PR #384), when a generator handler yields an error, the code in handle_job() breaks out of the streaming loop before calling stream_result():

if stream_output.get("error"):
    job_result = stream_output
    break                          # ← exits loop

await stream_result(...)           # ← never reached for errors

Clients listening on /stream receive normal chunks fine, but when an error occurs the stream goes silent. The error is saved internally (visible via /status), but never delivered through the stream.

Additionally, the error extraction replaced the entire dict:

stream_output = {"error": str(stream_output["output"]["error"])}

This discarded all other fields (context, refresh_worker, etc.).

PR #384's intent (marking errored jobs as FAILED instead of COMPLETED) is preserved — send_result() still receives job_result with the error and sets the correct status.

What changed

rp_job.pyhandle_job() generator loop:

  • Call await stream_result(session, stream_output, job) before break so errors reach the stream
  • Preserve extra fields from the error dict using dict unpacking instead of replacing the whole dict

test_job.py — 2 new tests:

  • Error is streamed before break (stream_result called with error payload)
  • Nested error preserves extra fields (context, refresh_worker survive extraction)

Test plan

  • All 31 tests in test_job.py pass (29 existing + 2 new)
  • New test verifies stream_result is called twice (once for normal chunk, once for error)
  • New test verifies extra fields (context, refresh_worker) are present in streamed error

Since v1.7.7 (PR runpod#384), when a generator handler yields an error the
code breaks out of the streaming loop before calling stream_result(),
so the error is never delivered to clients listening on /stream. The
error is saved for /status but the stream goes silent.

Additionally, the error extraction stripped all extra fields (context,
refresh_worker, etc.) by replacing the dict with {"error": msg}.

- Call stream_result() with the error BEFORE breaking out of the loop
- Preserve extra fields from the error dict alongside the error message
- Add tests for both streaming delivery and field preservation

Closes runpod#397
@Swigler
Swigler force-pushed the fix/stream-error-delivery branch from de830dd to 998a999 Compare September 3, 2026 17:56
@Swigler

Swigler commented Sep 3, 2026

Copy link
Copy Markdown
Author

Ping — errors during streaming are swallowed because the generator breaks before sending. This streams the error to the client first. Ready for review.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Breaking change in error handling in Serverless API with handler using generator

1 participant