Initial commit of the Flutter Cursor Generator project, including the core generator tool, project brief schema, example project setup, and CI configuration. Added README documentation outlining repository structure, quick start guide, and detailed descriptions of features and architecture pillars.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
---
|
||||
description: "Global error handling strategy for {{PROJECT_NAME}} — always applied"
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Global Error Handling — {{PROJECT_NAME}}
|
||||
|
||||
## 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');`
|
||||
Reference in New Issue
Block a user