fix(client): make space after "data:" optional in SSE parser#5306
fix(client): make space after "data:" optional in SSE parser#5306serhiizghama wants to merge 4 commits into
Conversation
Per the SSE spec, the single space after "data:" is optional. The
streamFlow parser was hardcoded to strip 6 characters ("data: "),
which corrupted the payload when an upstream emitted spec-compliant
events without the space (e.g. Spring WebFlux's ServerSentEvent writer)
and caused JSON.parse to throw on a truncated string.
There was a problem hiding this comment.
Code Review
This pull request updates the SSE parser in client.ts to correctly handle optional spaces after the data: prefix per the SSE specification and adds corresponding unit tests. A review comment identifies a potential TypeError when calling hasOwnProperty on a null or non-object result from JSON.parse and suggests a guard clause for better robustness.
| const chunk = JSON.parse(payload); | ||
| if (chunk.hasOwnProperty('message')) { | ||
| sendChunk(chunk.message); | ||
| } else if (chunk.hasOwnProperty('result')) { |
There was a problem hiding this comment.
The chunk variable resulting from JSON.parse(payload) could be null or a non-object type (e.g., if the payload is the string "null" or a number). Accessing hasOwnProperty on null will throw a TypeError. Adding a guard clause to ensure chunk is a non-null object improves robustness and prevents potential crashes on unexpected but valid JSON payloads.
const chunk = JSON.parse(payload);
if (!chunk || typeof chunk !== 'object') {
throw new Error('unknown chunk format: ' + JSON.stringify(chunk));
}
if (chunk.hasOwnProperty('message')) {
sendChunk(chunk.message);
} else if (chunk.hasOwnProperty('result')) {
Problem
streamFlow(js/genkit/src/client/client.ts) strips a hardcoded"data: "(6 characters) from each SSE event before passing the rest toJSON.parse. Per the SSE spec, the single space afterdata:is optional — sources are allowed to emitdata:foo. When they do (e.g. Spring WebFlux's built-inServerSentEventHttpMessageWriter), the current parser consumes the first character of the payload andJSON.parsethrows:Fixes #3728.
Solution
Strip the
data:prefix first, then strip at most one optional leading space — matching the SSE spec's "if value starts with a U+0020 SPACE character, remove it from value" rule.Testing
Added
tests/client_test.tscovering bothdata:{...}(no space) anddata: {...}(conventional) event forms. Local run: