---
description: "Global error handling strategy for TaskFlow — always applied"
alwaysApply: true
---

# Global Error Handling — TaskFlow

## Flutter error boundaries
Configure in `main.dart` — do this ONCE and never bypass it:

```dart
void main() {
  FlutterError.onError = (details) {
    FlutterError.presentError(details);
    // TODO: Send to crash reporter (Sentry/Firebase Crashlytics)
    crashReporter.recordFlutterError(details);
  };

  PlatformDispatcher.instance.onError = (error, stack) {
    // TODO: Send to crash reporter
    crashReporter.recordError(error, stack, fatal: true);
    return true;
  };

  runApp(const MyApp());
}
```

## Error types hierarchy
Define a sealed class for domain errors — never throw raw exceptions in business logic:

```dart
sealed class AppError {
  const AppError();
}
class NetworkError extends AppError { final int? statusCode; const NetworkError({this.statusCode}); }
class AuthError    extends AppError { final String reason; const AuthError(this.reason); }
class NotFoundError extends AppError { final String resource; const NotFoundError(this.resource); }
class UnknownError  extends AppError { final Object cause; const UnknownError(this.cause); }
```

## Repository layer
- Wrap ALL external calls in try/catch and return `Either<AppError, T>` or `Result<T>`
- NEVER let raw exceptions bubble to the presentation layer
- Log at the repository layer, not the UI layer

## Presentation layer
- Every async widget MUST handle error state explicitly — no silent failures
- Show user-friendly error messages: map `AppError` subtype → readable string
- Provide a "Try again" action for recoverable errors (network, timeout)
- For fatal errors (auth expired), redirect to login — never show a dead screen

## Crash reporting
- Integrate Sentry or Firebase Crashlytics before first TestFlight / Play beta
- Set `user` context on crash reporter after login (id only, no PII)
- Add `breadcrumbs` for key user actions to aid reproduction

## Logging strategy
```
Level     | Use case
DEBUG     | Development only (strip from release)
INFO      | Key user flows (login, purchase, etc.)
WARNING   | Recoverable errors, fallbacks used
ERROR     | Unrecoverable errors, unexpected states
```
- Use `logger` package — never bare `print()`
- Logger instance per class: `final _log = Logger('ClassName');`
