Skip to content

fix: preserve original stacks when an empty trace is supplied - #626

Merged
marandaneto merged 2 commits into
mainfrom
fix/empty-stack-fallback
Sep 30, 2026
Merged

marandaneto merged 2 commits into
mainfrom
fix/empty-stack-fallback

Conversation

@marandaneto

@marandaneto marandaneto commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

💡 Motivation and Context

Passing StackTrace.empty to exception capture skips the error's original stack and replaces it with capture-site frames. Empty string, Trace, and Chain representations can instead produce no frames because they are not equal to StackTrace.empty.

Treat empty and whitespace-only traces as missing. Preserve a usable supplied trace first, then the error's own trace, and generate a current stack only when neither is usable. Reuse the existing own-stack extraction helper for the primary exception and check emptiness by content.

This follows the SDK spec's stack preservation requirement. There are no public API changes or known divergences in the behavior changed here.

💚 How did you test it?

  • Added 19 focused cases for empty trace representations, whitespace, original-stack preservation, generated fallback, and usable supplied-stack precedence. These cover both direct errors and errors wrapped in PostHogException, including wrapper mechanism and handled-state preservation. Nine original regression cases and five wrapped-error cases fail on the pre-fix code. All pass with the fix.
  • Ran the regression cases outside the test runner's Chain.capture zone so test-harness frames cannot hide empty stacks.
  • Ran flutter test --no-pub in posthog_flutter: all 743 VM tests passed.
  • Ran make checkFormatDart, make analyzeDart, and make checkApiDart: all passed.
  • Audited the new tests and ran autoreview --mode branch --base origin/main on commit 05c1110: no actionable findings.
  • Browser tests and native example builds were not run.

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed. No documentation change is needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

The changeset was omitted at the author's request.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Pi used Git, GitHub CLI, Flutter/Dart checks, and isolated autoreview. The fix and before/after validation were performed in a dedicated worktree. The implementation reuses the existing stack extraction helper rather than adding a separate fallback path. The new tests were audited for regression sensitivity, and autoreview reported no actionable findings. Human review is required.

@marandaneto marandaneto self-assigned this Sep 30, 2026
@marandaneto

Copy link
Copy Markdown
Member Author

found while reviewing #621 but the issue was already there

@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Retrigger

[Medium risk] Changes how empty stack traces are detected and handled.

The PR appears safe to merge; the missing wrapped-error test is non-blocking.

Reviews (1) · Last reviewed commit: "fix: preserve original stacks when an em..."

Comment thread posthog_flutter/test/empty_stack_fallback_test.dart Outdated
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

posthog-flutter Compliance Report

Date: 2026-09-30 14:05:31 UTC
Duration: 96357ms

✅ All Tests Passed!

45/45 tests passed


Capture Tests

✅ 29/29 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields ✅ 122ms
Format Validation.Event Has Uuid ✅ 110ms
Format Validation.Event Has Lib Properties ✅ 108ms
Format Validation.Distinct Id Is String ✅ 107ms
Format Validation.Token Is Present ✅ 107ms
Format Validation.Custom Properties Preserved ✅ 109ms
Format Validation.Event Has Timestamp ✅ 109ms
Retry Behavior.Retries On 503 ✅ 5318ms
Retry Behavior.Does Not Retry On 400 ✅ 2112ms
Retry Behavior.Does Not Retry On 401 ✅ 2110ms
Retry Behavior.Respects Retry After Header ✅ 8110ms
Retry Behavior.Implements Backoff ✅ 15430ms
Retry Behavior.Retries On 500 ✅ 5217ms
Retry Behavior.Retries On 502 ✅ 5215ms
Retry Behavior.Retries On 504 ✅ 5216ms
Retry Behavior.Max Retries Respected ✅ 15430ms
Deduplication.Generates Unique Uuids ✅ 115ms
Deduplication.Preserves Uuid On Retry ✅ 5215ms
Deduplication.Preserves Uuid And Timestamp On Retry ✅ 10325ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 5221ms
Deduplication.No Duplicate Events In Batch ✅ 115ms
Deduplication.Different Events Have Different Uuids ✅ 109ms
Compression.Sends Gzip When Enabled ✅ 109ms
Batch Format.Uses Proper Batch Structure ✅ 108ms
Batch Format.Flush With No Events Sends Nothing ✅ 107ms
Batch Format.Multiple Events Batched Together ✅ 115ms
Error Handling.Does Not Retry On 403 ✅ 2113ms
Error Handling.Does Not Retry On 413 ✅ 2112ms
Error Handling.Retries On 408 ✅ 5217ms

Feature_Flags Tests

✅ 16/16 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 9ms
Request Payload.Flags Request Uses V2 Query Param ✅ 5ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 5ms
Request Payload.Flags Request Omits Authorization Header ✅ 6ms
Request Payload.Token In Flags Body Matches Init ✅ 5ms
Request Payload.Groups Round Trip ✅ 6ms
Request Payload.Groups Default To Empty Object ✅ 5ms
Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It ✅ 6ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 5ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 5ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 5ms
Request Lifecycle.No Flags Request On Init Alone ✅ 3ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 107ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 9ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 5ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 109ms

@marandaneto
marandaneto marked this pull request as ready for review September 30, 2026 13:56
@marandaneto
marandaneto requested a review from a team as a code owner September 30, 2026 13:56
@marandaneto
marandaneto merged commit 7939efa into main Sep 30, 2026
29 checks passed
@marandaneto
marandaneto deleted the fix/empty-stack-fallback branch September 30, 2026 14:53
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