mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-15 07:56:11 +08:00
150 lines
3.8 KiB
Dart
150 lines
3.8 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:device_info/device_info.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_crashlytics/flutter_crashlytics.dart';
|
|
import 'package:gitjournal/app.dart';
|
|
import 'package:gitjournal/settings.dart';
|
|
import 'package:package_info/package_info.dart';
|
|
import 'package:sentry/sentry.dart';
|
|
|
|
import 'package:gitjournal/.env.dart';
|
|
|
|
SentryClient _sentryClient;
|
|
Future<SentryClient> _initSentry() async {
|
|
return SentryClient(
|
|
dsn: environment['sentry'],
|
|
environmentAttributes: await _environmentEvent,
|
|
);
|
|
}
|
|
|
|
Future<SentryClient> getSentryClient() async {
|
|
return _sentryClient ??= await _initSentry();
|
|
}
|
|
|
|
Future<Event> get _environmentEvent async {
|
|
final packageInfo = await PackageInfo.fromPlatform();
|
|
final deviceInfoPlugin = DeviceInfoPlugin();
|
|
OperatingSystem os;
|
|
Device device;
|
|
if (Platform.isAndroid) {
|
|
final androidInfo = await deviceInfoPlugin.androidInfo;
|
|
os = OperatingSystem(
|
|
name: 'android',
|
|
version: androidInfo.version.release,
|
|
);
|
|
device = Device(
|
|
model: androidInfo.model,
|
|
manufacturer: androidInfo.manufacturer,
|
|
modelId: androidInfo.product,
|
|
);
|
|
} else if (Platform.isIOS) {
|
|
final iosInfo = await deviceInfoPlugin.iosInfo;
|
|
os = OperatingSystem(
|
|
name: iosInfo.systemName,
|
|
version: iosInfo.systemVersion,
|
|
);
|
|
device = Device(
|
|
model: iosInfo.utsname.machine,
|
|
family: iosInfo.model,
|
|
manufacturer: 'Apple',
|
|
);
|
|
}
|
|
final environment = Event(
|
|
release: '${packageInfo.version} (${packageInfo.buildNumber})',
|
|
contexts: Contexts(
|
|
operatingSystem: os,
|
|
device: device,
|
|
app: App(
|
|
name: packageInfo.appName,
|
|
version: packageInfo.version,
|
|
build: packageInfo.buildNumber,
|
|
),
|
|
),
|
|
userContext: User(
|
|
id: Settings.instance.pseudoId,
|
|
),
|
|
);
|
|
return environment;
|
|
}
|
|
|
|
void flutterOnErrorHandler(FlutterErrorDetails details) {
|
|
if (reportCrashes == true) {
|
|
// vHanda: This doesn't always call our zone error handler, why?
|
|
// Zone.current.handleUncaughtError(details.exception, details.stack);
|
|
reportError(details.exception, details.stack);
|
|
} else {
|
|
FlutterError.dumpErrorToConsole(details);
|
|
}
|
|
}
|
|
|
|
bool get reportCrashes => _reportCrashes ??= _initReportCrashes();
|
|
bool _reportCrashes;
|
|
bool _initReportCrashes() {
|
|
return !JournalApp.isInDebugMode && Settings.instance.collectCrashReports;
|
|
}
|
|
|
|
Future<void> initCrashlytics() async {
|
|
if (reportCrashes) {
|
|
await FlutterCrashlytics().initialize();
|
|
}
|
|
}
|
|
|
|
Future<void> reportError(Object error, StackTrace stackTrace) async {
|
|
if (reportCrashes) {
|
|
captureSentryException(error, stackTrace);
|
|
}
|
|
|
|
print("Uncaught Exception: $error");
|
|
print(stackTrace);
|
|
}
|
|
|
|
Future<void> logException(Exception e, StackTrace stackTrace) async {
|
|
if (!reportCrashes) {
|
|
return;
|
|
}
|
|
|
|
await captureSentryException(e, stackTrace);
|
|
return FlutterCrashlytics().logException(e, stackTrace);
|
|
}
|
|
|
|
Future<void> logExceptionWarning(Exception e, StackTrace stackTrace) async {
|
|
if (!reportCrashes) {
|
|
return;
|
|
}
|
|
|
|
await captureSentryException(e, stackTrace, level: SeverityLevel.warning);
|
|
return FlutterCrashlytics().logException(e, stackTrace);
|
|
}
|
|
|
|
List<Breadcrumb> breadcrumbs = [];
|
|
|
|
void captureErrorBreadcrumb({
|
|
@required String name,
|
|
Map<String, String> parameters,
|
|
}) {
|
|
var b = Breadcrumb(name, DateTime.now(), data: parameters);
|
|
breadcrumbs.add(b);
|
|
}
|
|
|
|
Future<void> captureSentryException(
|
|
Object exception,
|
|
StackTrace stackTrace, {
|
|
SeverityLevel level = SeverityLevel.error,
|
|
}) async {
|
|
try {
|
|
final sentry = await getSentryClient();
|
|
final Event event = Event(
|
|
exception: exception,
|
|
stackTrace: stackTrace,
|
|
breadcrumbs: breadcrumbs,
|
|
level: level,
|
|
);
|
|
|
|
return sentry.capture(event: event);
|
|
} catch (e) {
|
|
print("Failed to report with Sentry: $e");
|
|
}
|
|
}
|