Error Reporting Widget
The Error Reporting Widget is a global monitoring and diagnostic tool integrated into the Flow mobile app. it captures both uncaught system exceptions and handled backend errors, providing a seamless way for users to report issues with rich diagnostic context.
Overview
The reporting system consists of:
- Global Catchers: Hooks into
FlutterError.onErrorandPlatformDispatcher.instance.onErrorto catch layout and async crashes. - Manual Reporting: A
LogServiceintegration that allows developers to trigger the report UI fromtry-catchblocks. - UI Overlay: A premium dark-mode modal (
ErrorReporterOverlay) that appears when an error is detected. - Backend Storage: A dedicated
app_issuestable in Supabase for tracking and triaging reports.
Architecture
graph TD A[Flutter App] --> B{Error Type} B -- Uncaught --> C[Global Error Handler] B -- Handled --> D[LogService.reportError] C --> E[ErrorNotifier] D --> E E --> F[ErrorReporterOverlay] F --> G[IssueReportService] G --> H[Supabase app_issues]
Frontend Implementation
The core logic resides in lib/shared/notifiers/error_notifier.dart and lib/shared/widgets/error_reporter_overlay.dart.
- Diagnostic Data: Automatically collects device model, OS version, app version (build number), and user ID.
- State Management: Uses Riverpod
errorNotifierProviderto manage the visibility and payload of the error state.
Backend Implementation
Reports are stored in the app_issues table with the following schema:
| Column | Type | Description |
|---|---|---|
id | UUID | Unique identifier (Primary Key) |
user_id | UUID | Reference to auth.users (nullable) |
error_message | TEXT | The exception message or error description |
stack_trace | TEXT | Full stack trace for debugging |
device_info | JSONB | Platform-specific diagnostic data |
user_description | TEXT | User’s feedback on what they were doing |
app_version | TEXT | Version and build Number (e.g., 1.0.0+1) |
status | TEXT | new, investigating, resolved, ignored |
Usage
Automatic Tracking
No action is required for layout or uncaught async errors. They are intercepted in main.dart and will trigger the UI automatically.
Manual Reporting
To report an error that you’ve caught in a try-catch block (e.g., a backend response error or a data parsing issue):
try {
// Your code...
} catch (e, stack) {
LogService.instance.reportError(e, stack);
}Maintenance
Admins can view and triage issues directly from the Supabase dashboard or via the app_issues table. The updated_at trigger ensures the modification time is tracked when the status changes.