Skip to content

fix(analytics): surface polling-loop errors so schema drift can't loop silently (SDK-78)#156

Closed
tylerjroach wants to merge 1 commit into
masterfrom
fix/sdk-78-surface-polling-errors
Closed

fix(analytics): surface polling-loop errors so schema drift can't loop silently (SDK-78)#156
tylerjroach wants to merge 1 commit into
masterfrom
fix/sdk-78-surface-polling-errors

Conversation

@tylerjroach

Copy link
Copy Markdown
Contributor

Summary

start_polling_for_definitions! caught StandardError and dispatched only to @error_handler, whose default Mixpanel::ErrorHandler#handle is a no-op. Schema drift (NoMethodError, JSON::ParserError, TypeError, …) would loop forever undetected unless the user had configured a custom handler — exactly the audit's concern.

Add a log_polling_error helper that always warns to $stderr before dispatching to @error_handler. Visibility no longer depends on configuration; operators see the failure in their logs the moment the next poll hits a bad payload.

Why a warn and not a re-raise

Matches the de facto convention across every other Mixpanel SDK polling loop:

SDK Behavior
mixpanel-python logger.exception("Failed to fetch feature flag definitions"), continue
mixpanel-java logger.log(Level.WARNING, "Failed to fetch flag definitions", e), continue
mixpanel-go log.Printf("Error polling for flag definitions: %v", err), continue
mixpanel-node this.logger?.error(...), continue

Crashing the polling thread on the first bad payload would freeze local evaluation at whatever variants were last cached — strictly worse than continuing. The audit's complaint was about detection, not retry policy.

Context

Linear: SDK-78. Source: Feature Flags & OpenFeature SDK Audit Findings. Ruby was the only affected SDK — the rest already log unconditionally.

Independent of SDK-81 (the polling-thread-safety fix); changes are in different lines of the same begin/rescue block and will merge cleanly in either order.

Test plan

  • Full flags spec suite (46 examples) passes
  • New "warns to stderr when fetch raises and no error_handler is configured" exercises the audit-failure mode directly (provider built with nil error_handler + 500 response, asserts the warn lands on stderr)
  • New "surfaces unexpected errors (schema drift) instead of swallowing them silently" injects a NoMethodError via allow(...).to receive(:fetch_flag_definitions), asserts both the error_handler dispatch AND the stderr warning fire

🤖 Generated with Claude Code

…p silently

start_polling_for_definitions! caught StandardError and dispatched only
to @error_handler (whose default ErrorHandler#handle is a no-op), so
NoMethodError / JSON::ParserError / etc. from schema drift would loop
forever undetected unless the user had configured a custom handler.

Add log_polling_error which always warns to STDERR before dispatching
to @error_handler — visibility no longer depends on configuration.
Matches the convention in mixpanel-python, mixpanel-java, mixpanel-go,
and mixpanel-node, all of which log unconditionally and continue
polling.

Linear: SDK-78

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@tylerjroach tylerjroach requested review from a team and ketanmixpanel June 29, 2026 18:35
@linear-code

linear-code Bot commented Jun 29, 2026

Copy link
Copy Markdown

SDK-78

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 96.66%. Comparing base (e5edf71) to head (54a7b06).

Files with missing lines Patch % Lines
lib/mixpanel-ruby/flags/local_flags_provider.rb 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #156      +/-   ##
==========================================
+ Coverage   96.64%   96.66%   +0.01%     
==========================================
  Files          14       14              
  Lines         656      659       +3     
==========================================
+ Hits          634      637       +3     
  Misses         22       22              
Flag Coverage Δ
openfeature 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tylerjroach

Copy link
Copy Markdown
Contributor Author

Folded into #155 — both fixes touch the same begin/rescue block in start_polling_for_definitions!, simpler as one PR.

@tylerjroach tylerjroach deleted the fix/sdk-78-surface-polling-errors branch June 29, 2026 18:42
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.

1 participant