Commit Graph

2 Commits

Author SHA1 Message Date
be50448917 V3-12: crash reporting (code only)
shouldInitializeCrashReporting() and scrubExtra() are pure, fully unit-tested decision/scrubbing functions wired into sentry_flutter via beforeSend/beforeBreadcrumb. Config.crashReportingEnabled defaults off; the DSN is a compile-time --dart-define, not a preference. RecordingEngine gained an injected onUnexpectedStop callback, firing once when restoreAfterProcessDeath finds a trip still 'recording' at launch -- the process died without a user stop.

Marked partially done: the ticket's real acceptance criteria (a forced crash landing in a real Sentry project from a release build, inspecting a real payload) need a Sentry account and a release build this environment can't produce.
2026-08-17 19:32:54 -05:00
5a7c598610 T10/T11: location seam and recording pipeline; fix a native crash-recovery bug
T10 -- LocationSource abstraction plus FakeLocationSource, so the riskiest code
in the app is testable with no device. Also found that geolocator ships its own
Android foreground service with enableWakeLock, which could drop
flutter_foreground_task and both its deprecation paths; deferred to T12 since it
costs notification actions.

T11 -- the pipeline. Kotlin's unbounded Channel plus blocking-receive writer
becomes a List buffer plus a periodic Timer; Dart's event loop makes a blocking
receive unnecessary and the guarantee is unchanged, since the fix callback only
appends and returns. 24 tests.

Found a real bug in the native app while porting. restoreAfterProcessDeath says
it resumes into a new segment because the dead time is a real gap, but it calls
resumeTrip, which adopts the segment a crash left open. After a pause that is
right; after a crash nothing closed it. Points either side of the dead time then
share a segment, and computeSummary -- the authoritative pass that overwrites the
live estimate on completion -- measures straight through the gap. Reverting the
fix and running the guard shows 111,217 m of phantom distance.

Fixed via TripRepository.resumeIntoNewSegment, which closes the stale segment at
its last recorded point rather than at now, so the dead time is not billed as
ride time either. A deliberate, documented departure from parity: the code
contradicted its own comment and produced silently wrong data.

The first version of that guard passed with the bug still present -- the fixture
used pause(), which closes the segment and stops reproducing the crash. Caught
only by reverting the fix and checking the test failed.

145 tests passing, analyze clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 11:19:21 -05:00