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.
This commit is contained in:
2026-08-17 19:32:54 -05:00
parent 0e605ef174
commit be50448917
14 changed files with 443 additions and 9 deletions

View File

@@ -14,6 +14,7 @@ import '../config/config.dart';
import '../data/database.dart';
import '../data/trip_repository.dart';
import '../domain/models.dart';
import '../crash/crash_reporter.dart';
import '../data/route_plan_repository.dart';
import '../notification/ride_notification_controller.dart';
import '../notification/ride_notification_coordinator.dart';
@@ -69,6 +70,8 @@ final recordingEngineProvider = Provider<RecordingEngine>((ref) {
repository: ref.watch(tripRepositoryProvider),
locationSource: ref.watch(locationSourceProvider),
uploadPending: () async => ref.read(uploaderProvider)?.uploadPending(),
onUnexpectedStop: (reason) =>
reportUnexpectedRecordingStop(reason: reason),
);
ref.onDispose(engine.dispose);
return engine;
@@ -120,6 +123,14 @@ final mountedModeProvider = StateProvider<bool>(
(ref) => ref.watch(configProvider)?.mountedMode ?? false,
);
/// V3-12: same shape again. Note that flipping this at runtime does not retroactively
/// start or stop a Sentry client already initialised at app launch -- see
/// `maybeInitCrashReporting`'s doc comment on why that gate is checked once, in
/// `main()`, not read reactively.
final crashReportingEnabledProvider = StateProvider<bool>(
(ref) => ref.watch(configProvider)?.crashReportingEnabled ?? false,
);
/// Overridden in tests with [FakeWakelockController].
final wakelockControllerProvider = Provider<WakelockController>(
(ref) => PlusWakelockController(),