Skip to content

fix: coerce null variations + FBEvent Flow + per-flag isolation on sync - #12

Merged
KaustubhNBhangre merged 1 commit into
mainfrom
fix/coerce-null-variation-and-events
Aug 12, 2026
Merged

fix: coerce null variations + FBEvent Flow + per-flag isolation on sync#12
KaustubhNBhangre merged 1 commit into
mainfrom
fix/coerce-null-variation-and-events

Conversation

@Devild007

Copy link
Copy Markdown
Contributor

Summary

Three resilience fixes surfaced by real-world testing against a live FeatBit deployment.

  1. coerceInputValues = true on both Json configs (StreamingJson + FbApiClient.json).
    Server occasionally ships "variation": null in streaming payloads for json-typed
    flags with an unset variation slot. Without coercion the whole payload fails to decode
    with Expected string value for a non-null key 'variation', got null literal,
    startTask never completes, and FBClient stays not-ready for its whole lifetime.
    With coercion, null coerces to the property default ("") and streaming proceeds.

  2. Per-flag try/catch around store.upsert in both StreamingDataSynchronizer and
    PollingDataSynchronizer.safePoll. If a single flag entry slips past coercion (or throws
    for any other reason), we log-and-skip that entry instead of aborting the whole batch.
    FBClient still becomes ready with the surviving flags.

  3. New FBClient.events(): Flow<FBEvent> API. Applications subscribe to surface
    transport / decode failures (Ready, Reconnecting, SyncError, TransportError) into
    their own observability stack (Sentry, Timber). SyncError.recoverable disambiguates
    one-bad-flag-in-batch from a full sync outage. README updated with the collector pattern.

Version bumped to 0.1.1-SNAPSHOT so JitPack consumers requesting this branch get a distinct
artifact.

Verification

  • ./gradlew :featbit-client:build — green
  • ./gradlew test — green
  • Smoke-tested end-to-end against a live FeatBit dev environment (Fluent Health):
    before the fix, FBClient failed to start within 5s on every launch due to the null
    variation crash; after the fix, FBClient successfully started in ~0.6s and the
    downstream Android app receives the expected flag variation string.

Test plan

  • Reviewer confirms coerceInputValues semantics: null on a defaulted non-null
    String field → property default rather than throw.
  • Reviewer confirms FBEvent shape matches expected observability surface (Timber /
    Sentry mapping shown in README).
  • JitPack produces v0.1.1 after merge + tag.

🤖 Generated with Claude Code

Three related resilience fixes surfaced by real-world testing against the
els.fluentinhealth.io FeatBit server.

1. coerceInputValues = true on both Json configs (StreamingJson +
   FbApiClient.json). Server occasionally ships `"variation": null` in
   streaming payloads for json-typed flags with an unset variation slot;
   without coercion the whole payload fails to decode with
   `Expected string value for a non-null key 'variation', got null literal`,
   startTask never completes, and FBClient stays not-ready for its whole
   lifetime. With coercion, null coerces to the property default ("")
   and streaming proceeds.

2. Per-flag try/catch around store.upsert in both StreamingDataSynchronizer
   and PollingDataSynchronizer.safePoll. If a single flag entry ever slips
   past coercion (or throws for any other reason), we log-and-skip that
   entry instead of aborting the whole batch. FBClient still becomes ready
   with the surviving flags.

3. New FBClient.events(): Flow<FBEvent> API. Applications subscribe to
   surface transport / decode failures (Ready, Reconnecting, SyncError,
   TransportError) into their own observability stack (Sentry, Timber).
   SyncError.recoverable disambiguates one-bad-flag-in-batch from a full
   sync outage. README updated with the collector pattern.

Version bumped to 0.1.1-SNAPSHOT so consumers requesting this branch via
JitPack get a distinct artifact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Devild007
Devild007 force-pushed the fix/coerce-null-variation-and-events branch from 7af619a to 853515e Compare August 11, 2026 17:38
@KaustubhNBhangre
KaustubhNBhangre merged commit 1929e96 into main Aug 12, 2026
5 checks passed
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.

3 participants