oncall_error_tracking 0.1.2
oncall_error_tracking: ^0.1.2 copied to clipboard
Flutter SDK for error tracking with automatic capture, breadcrumbs, user context, tags, and retries.
example/main.dart
import 'package:flutter/material.dart';
import 'package:oncall_error_tracking/oncall_error_tracking.dart';
/// Complete example of OnCall Error Tracking SDK integration.
///
/// This demonstrates:
/// - SDK initialization with full configuration
/// - Automatic Flutter error capture
/// - Zone-based async error catching
/// - Navigation breadcrumbs
/// - Manual error and message capture
/// - User context and tags
void main() {
// 1. Initialize the SDK
final client = OnCallClient.init(OnCallOptions(
dsn: 'https://abc123@errors.oncallteams.com/api/project-id/store',
environment: 'production',
release: '1.0.0+1',
sampleRate: 1.0, // Send 100% of events
maxBreadcrumbs: 100,
debug: true, // Enable console logging (disable in production)
beforeSend: (event) {
// Optional: filter or modify events before sending
// Return null to drop the event
return event;
},
));
// 2. Install Flutter framework error handler
installFlutterErrorHandler(client);
// 3. Wrap the app in a zone to catch async errors
runWithOnCall(client, () {
runApp(const MyApp());
});
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'OnCall Error Tracking Demo',
// 4. Add navigator observer for route breadcrumbs
navigatorObservers: [
OnCallNavigatorObserver(OnCallClient.instance!),
],
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
// 5. Set user context after login
OnCallClient.instance?.setUser({
'id': 'user-123',
'email': 'user@example.com',
'username': 'demo_user',
});
// 6. Set tags for filtering in the dashboard
OnCallClient.instance?.setTag('plan', 'premium');
OnCallClient.instance?.setTag('locale', 'en-US');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Error Tracking Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Trigger a handled exception
ElevatedButton(
onPressed: () async {
try {
throw Exception('This is a test exception');
} catch (e, stackTrace) {
// 7. Manually capture handled exceptions
await OnCallClient.instance?.captureException(
e,
stackTrace: stackTrace,
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Exception captured!')),
);
}
}
},
child: const Text('Capture Exception'),
),
const SizedBox(height: 16),
// Send a diagnostic message
ElevatedButton(
onPressed: () async {
// 8. Add a custom breadcrumb
OnCallClient.instance?.addBreadcrumb(
category: 'ui',
message: 'User tapped "Send Message" button',
level: 'info',
data: {'screen': 'home'},
);
// 9. Capture an informational message
await OnCallClient.instance?.captureMessage(
'User completed onboarding flow',
level: 'info',
);
},
child: const Text('Send Message'),
),
const SizedBox(height: 16),
// Trigger an unhandled exception (caught by zone)
ElevatedButton(
onPressed: () {
// This will be caught by runWithOnCall's zone
Future.delayed(Duration.zero, () {
throw StateError('Unhandled async error for testing');
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
),
child: const Text('Trigger Unhandled Error'),
),
],
),
),
);
}
}