exampleMain function
void
exampleMain()
APPROACH 2: Manual Sentry integration (for more control) Use this if you need more control over initialization order or want to use the ErrorReporter interface pattern
IMPORTANT: This approach does NOT use appRunner, so you must:
- Call initialize() on the reporter before runApp()
- Set managesOwnErrorHandlers: false in ErrorReportingConfig
- Let Dreamic's appInitErrorHandling() set up error handlers
Example Sentry implementation
To use this:
- Add sentry_flutter to your pubspec.yaml
- Uncomment the Sentry import above and the implementation below
- Configure in your main() function before calling appInitErrorHandling()
// pubspec.yaml
dependencies:
sentry_flutter: ^9.7.0
Build commands with environment configuration:
# Development build
flutter build ios --dart-define=ENVIRONMENT_TYPE=development
# Staging build
flutter build ios --dart-define=ENVIRONMENT_TYPE=staging
# Production build
flutter build ios --dart-define=ENVIRONMENT_TYPE=production
Example main.dart setup
Implementation
/*
class SentryErrorReporter implements ErrorReporter {
final String dsn;
final String? environment;
final String? release;
SentryErrorReporter({
required this.dsn,
this.environment,
this.release,
});
@override
Future<void> initialize() async {
// Get the app version for release tracking
final appRelease = release ?? await AppConfigBase.getReleaseId();
// IMPORTANT: This does NOT use appRunner
// Error handlers are managed by Dreamic's appInitErrorHandling()
await SentryFlutter.init(
(options) {
options.dsn = dsn;
// Use ENVIRONMENT_TYPE dart-define or fallback to parameter
options.environment = environment ?? AppConfigBase.environmentType.value;
// Use the app version for release tracking
options.release = appRelease;
options.tracesSampleRate = 1.0;
// Optional: Add custom configuration
options.beforeSend = (event, hint) {
// You can modify or filter events here
return event;
};
},
// DO NOT use appRunner here - error handlers managed by Dreamic
);
}
@override
void recordError(Object error, StackTrace? stackTrace) {
Sentry.captureException(
error,
stackTrace: stackTrace,
);
}
@override
void recordFlutterError(FlutterErrorDetails details) {
Sentry.captureException(
details.exception,
stackTrace: details.stack,
);
}
// Additional helper methods for Sentry-specific features
void setUserContext(String userId, String email, String username) {
Sentry.configureScope((scope) {
scope.user = SentryUser(
id: userId,
email: email,
username: username,
);
});
}
void addBreadcrumb(String message, String category) {
Sentry.addBreadcrumb(
Breadcrumb(
message: message,
category: category,
timestamp: DateTime.now(),
),
);
}
void setTag(String key, String value) {
Sentry.configureScope((scope) {
scope.setTag(key, value);
});
}
}
*/
/// Example main.dart setup
void exampleMain() async {
WidgetsFlutterBinding.ensureInitialized();
// ==================================================================================
// APPROACH 1 (RECOMMENDED): Use Sentry's appRunner wrapper
// ==================================================================================
// This is Sentry's recommended approach - see exampleMainSentryWrapper() above
//
// Summary:
// - Use SentryFlutter.init() with appRunner parameter
// - Sentry manages all error handlers automatically
// - DO NOT call appInitErrorHandling()
// - Clean and simple setup
//
// Example:
/*
await SentryFlutter.init(
(options) {
options.dsn = 'https://your-dsn@sentry.io/project-id';
options.environment = AppConfigBase.environmentType.value;
options.release = await AppConfigBase.getReleaseId();
options.tracesSampleRate = 1.0;
},
appRunner: () => appRunIfValidVersion(() => MyApp()),
);
return; // Exit main - app is running
*/
// ==================================================================================
// APPROACH 2: Manual integration with Dreamic's error handling
// ==================================================================================
// Use this if you need more control or want to use the ErrorReporter interface
// OPTION 1: Use Sentry only (recommended for web apps)
/*
// Environment and release are automatically configured
// Environment uses ENVIRONMENT_TYPE dart-define (see AppConfigBase.environmentType)
// Release is auto-generated from app version (see AppConfigBase.getReleaseId())
configureErrorReporting(
ErrorReportingConfig.customOnly(
reporter: SentryErrorReporter(
dsn: 'https://your-dsn@sentry.io/project-id',
// environment and release auto-configured from AppConfigBase
),
enableOnWeb: true, // Sentry works on web
enableInDebug: false, // Disable in debug mode
managesOwnErrorHandlers: false, // We're using manual integration
),
);
// Initialize error handling with configured reporter
await appInitErrorHandling();
// Run your app
runApp(MyApp());
*/
// OPTION 2: Use both Firebase Crashlytics and Sentry
/*
configureErrorReporting(
ErrorReportingConfig.both(
reporter: SentryErrorReporter(
dsn: 'https://your-dsn@sentry.io/project-id',
// environment and release auto-configured from AppConfigBase
),
enableOnWeb: false, // Crashlytics doesn't work on web
enableInDebug: false,
customReporterManagesErrorHandlers: false,
),
);
// Initialize error handling with configured reporter
await appInitErrorHandling();
// Run your app
runApp(MyApp());
*/
// OPTION 3: Use Firebase Crashlytics only (default)
/*
configureErrorReporting(
ErrorReportingConfig.firebaseOnly(
enableInDebug: false,
enableOnWeb: false,
),
);
// Or simply don't call configureErrorReporting() at all
// Initialize error handling with configured reporter
await appInitErrorHandling();
// Continue with your app initialization...
runApp(MyApp());
*/
}