Skip to content

fix(cli_tools): Prevent analytics send failures from crashing the host process#125

Merged
nielsenko merged 1 commit into
serverpod:mainfrom
nielsenko:fix-missing-async
Jun 11, 2026
Merged

fix(cli_tools): Prevent analytics send failures from crashing the host process#125
nielsenko merged 1 commit into
serverpod:mainfrom
nielsenko:fix-missing-async

Conversation

@nielsenko

@nielsenko nielsenko commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Make both providers' sendEvent properly async so they return reified Future<void>s, and harden Analytics.track to swallow errors with try/catch instead of catchError, so implementations returning foreign futures cannot crash the process.

Summary by CodeRabbit

  • Refactor

    • Improved error handling and reliability in analytics event tracking.
    • Enhanced control flow in event transmission to ensure proper completion handling.
  • Tests

    • Added test coverage to verify error handling in analytics operations remains robust.

@nielsenko nielsenko self-assigned this Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@nielsenko, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 55 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3783d778-932d-4805-bf7b-1499877b5883

📥 Commits

Reviewing files that changed from the base of the PR and between 8955c12 and e3a0cd9.

📒 Files selected for processing (4)
  • packages/cli_tools/lib/src/analytics/analytics.dart
  • packages/cli_tools/lib/src/analytics/mixpanel.dart
  • packages/cli_tools/lib/src/analytics/posthog.dart
  • packages/cli_tools/test/analytics/analytics_test.dart
📝 Walkthrough

Walkthrough

Analytics.track error handling is refactored to use a new _quietSendEvent helper for centralized error swallowing. MixPanelAnalytics and PostHogAnalytics are updated to explicit async/await in sendEvent instead of returning futures directly. A test validates flush() succeeds despite sendEvent failures.

Changes

Analytics Error Handling and Async Control Flow

Layer / File(s) Summary
Analytics.track refactoring and quiet-send helper
packages/cli_tools/lib/src/analytics/analytics.dart
Analytics.track now calls a new private _quietSendEvent async helper instead of inline error handling. The helper wraps sendEvent in try/catch and ensures the pending future is removed from _pendingTracks on completion, whether the send succeeds or fails.
Provider sendEvent async/await conversion
packages/cli_tools/lib/src/analytics/mixpanel.dart, packages/cli_tools/lib/src/analytics/posthog.dart
MixPanelAnalytics.sendEvent and PostHogAnalytics.sendEvent are converted to async methods that await HTTP calls instead of returning futures directly. This ensures the Future<void> contract properly completes after timeout handling finishes.
Error handling and edge-case test coverage
packages/cli_tools/test/analytics/analytics_test.dart
New test verifies flush() completes successfully even when sendEvent fails. NonVoidFutureAnalytics test implementation intentionally declares sendEvent as Future<void> while returning a Future<String>, validating edge-case behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • serverpod/cli_tools#107: Directly builds on the flush flow refactor; this PR refactors track/pending-send error handling to support the earlier flush base-class changes.
  • serverpod/cli_tools#100: Earlier analytics provider refactor touching the same track and sendEvent implementations.

Suggested reviewers

  • christerswahn
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: preventing analytics send failures from crashing the host process, which aligns directly with the PR objectives and file changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/cli_tools/test/analytics/analytics_test.dart (1)

51-69: ⚡ Quick win

Make the test name more behavior-focused.

The test name describes implementation details ("whose sendEvent returns a future with a non-void reified type") rather than observable behavior. As per coding guidelines, test names should describe behavior, not implementation.

Consider rewording to focus on what the test verifies from a behavioral perspective:

  • "Given analytics with a failing event send, when flushing, then flush completes successfully despite underlying future type issues."

Or more concisely:

  • "Given analytics with a failing send event, when flushing, then flush ignores the failure and completes."

This would align better with the behavioral descriptions used in the other tests (e.g., "pending event", "send fails").

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli_tools/test/analytics/analytics_test.dart` around lines 51 - 69,
Rename the test that currently starts with "Given an analytics implementation
whose sendEvent returns a future with a non-void reified type..." to a
behavior-focused description; locate the test(...) invocation and replace the
long implementation-detail name with a concise behavioral name such as "Given
analytics with a failing send event, when flushing, then flush ignores the
failure and completes" (or the alternative "Given analytics with a failing event
send, when flushing, then flush completes successfully despite underlying future
type issues") so the test describes observable behavior rather than
implementation details.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/cli_tools/test/analytics/analytics_test.dart`:
- Around line 51-69: Rename the test that currently starts with "Given an
analytics implementation whose sendEvent returns a future with a non-void
reified type..." to a behavior-focused description; locate the test(...)
invocation and replace the long implementation-detail name with a concise
behavioral name such as "Given analytics with a failing send event, when
flushing, then flush ignores the failure and completes" (or the alternative
"Given analytics with a failing event send, when flushing, then flush completes
successfully despite underlying future type issues") so the test describes
observable behavior rather than implementation details.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0b162de1-f811-48ff-82cd-8f1457e05f75

📥 Commits

Reviewing files that changed from the base of the PR and between 539e21f and 8955c12.

📒 Files selected for processing (4)
  • packages/cli_tools/lib/src/analytics/analytics.dart
  • packages/cli_tools/lib/src/analytics/mixpanel.dart
  • packages/cli_tools/lib/src/analytics/posthog.dart
  • packages/cli_tools/test/analytics/analytics_test.dart

@marcelomendoncasoares marcelomendoncasoares left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analyzer if failing, but the solution LGTM!

…t process

Make both providers' `sendEvent` properly async so they return reified
`Future<void>`s, and harden `Analytics.track` to swallow errors with
try/catch instead of `catchError`, so implementations returning foreign
futures cannot crash the process.
@nielsenko nielsenko force-pushed the fix-missing-async branch from 8955c12 to e3a0cd9 Compare June 11, 2026 11:59
@nielsenko nielsenko merged commit 2dcce5b into serverpod:main Jun 11, 2026
24 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.

2 participants