Fix/sse empty data format exception#153
Conversation
madhuchavva
left a comment
There was a problem hiding this comment.
Inline review comment on SSE malformed payload handling.
| lastKnownId = sseModel.id; | ||
| String jsonData = sseModel.data ?? ""; | ||
| Map<String, dynamic> jsonMap = jsonDecode(jsonData); | ||
| Map<String, dynamic> jsonMap = jsonDecode(data); |
There was a problem hiding this comment.
This fixes the heartbeat/empty-data case, which is good. There is still one related robustness gap: non-empty malformed data can still throw inside this async .listen() callback. If the server sends truncated JSON, invalid JSON, or a payload shape that is not Map<String, dynamic>, jsonDecode(data) can escape the surrounding request try/catch and become an unhandled async error. Can we wrap decode/type validation locally and route failures through onError or intentionally ignore only known heartbeat/keepalive events?
There was a problem hiding this comment.
Fixed, wrapped jsonDecode and the type check in a local try/catch inside the .listen() callback — all parse failures now route through onError instead of escaping as unhandled async errors. Added tests for malformed JSON and non-object payloads.
madhuchavva
left a comment
There was a problem hiding this comment.
Requesting changes based on the inline review comments. The notes call out functional gaps or compatibility/documentation risks that should be addressed before merge.
fix: handle empty SSE data payload to prevent unhandled FormatException
Problem
When a GrowthBook SSE stream emits a heartbeat or keepalive event with an empty
datafield, the SDK crashed with an unhandledFormatException.The root cause was a two-part issue:
sseModel.data ?? ""silently fell through tojsonDecode(""), which throws aFormatExceptionon an empty string..listen()callback runs asynchronously, so the exception escaped the surroundingtry/catchand became an unhandled error — crashing the listener silently in production.Fix
In lib/src/Network/network.dart, the
featuresevent handler now guards against empty or null payloads before attempting JSON decoding:Heartbeat/keepalive events are silently dropped. JSON parsing is only attempted when there is actual data.
Tests
Added test/common_test/sse_empty_data_test.dart covering:
datafield (data:) — no unhandled exception,onSuccessnot calleddatafield (null) — no unhandled exception,onSuccessnot calledonSuccesscalled with the parsed map