From 8fafc45fa699cc1b60a5a9223769c933bfda971c Mon Sep 17 00:00:00 2001 From: Nico Mexis Date: Mon, 20 May 2024 18:12:14 +0200 Subject: [PATCH] Merge #32 and improve a few things --- lib/core/catcher_2.dart | 43 ++++++++++++++++---------------- lib/handlers/http_handler.dart | 6 +++-- lib/handlers/sentry_handler.dart | 33 ++++++++++-------------- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/lib/core/catcher_2.dart b/lib/core/catcher_2.dart index d63055d..dc97877 100644 --- a/lib/core/catcher_2.dart +++ b/lib/core/catcher_2.dart @@ -87,7 +87,7 @@ class Catcher2 implements ReportModeAction { _setupErrorHooks(); - _initWidgetBindingAndRunApp(); + _initWidgetsBindingAndRunApp(); // Loading device and application info requires that the widgets binding is // initialized so we need to run it after we init WidgetsFlutterBinding. @@ -184,17 +184,15 @@ class Catcher2 implements ReportModeAction { }; // PlatformDispatcher.instance.onError catches ASYNCHRONOUS errors, but it - // does not work for web, most likely due to this issue: + // currently does not work for Web, most likely due to this issue: // https://github.com/flutter/flutter/issues/100277 - if (!kIsWeb) { - PlatformDispatcher.instance.onError = (error, stack) { - _reportError(error, stack); - _currentConfig.onPlatformError?.call(error, stack); - return true; - }; - } + PlatformDispatcher.instance.onError = (error, stack) { + _reportError(error, stack); + _currentConfig.onPlatformError?.call(error, stack); + return true; + }; - /// Web doesn't have Isolate error listener support + // Web doesn't have Isolate error listener support if (!kIsWeb) { Isolate.current.addErrorListener( RawReceivePort((pair) async { @@ -208,21 +206,17 @@ class Catcher2 implements ReportModeAction { } } - void _initWidgetBindingAndRunApp() { - if (!kIsWeb) { - // This isn't web, we can just run the app, no need for runZoneGuarded - // since async errors are caught by PlatformDispatcher.instance.onError. - _initWidgetsBindingIfNeeded(); - _runApp(); - } else { - // We are in a web environment so we need runZoneGuarded to catch async - // exceptions. + void _initWidgetsBindingAndRunApp() { + if (kIsWeb) { + // Due to https://github.com/flutter/flutter/issues/100277 + // this is still needed... As soon as proper error catching support + // for Web is implemented, this branch should be merged with the other. unawaited( runZonedGuarded>( () async { // It is important that we run init widgets binding inside the - // runZonedGuarded call to be able to catch the async execeptions. - _initWidgetsBindingIfNeeded(); + // runZonedGuarded call to be able to catch the async exceptions. + _initWidgetsBinding(); _runApp(); }, (error, stack) { @@ -231,6 +225,11 @@ class Catcher2 implements ReportModeAction { }, ), ); + } else { + // This isn't Web, we can just run the app, no need for runZoneGuarded + // since async errors are caught by PlatformDispatcher.instance.onError. + _initWidgetsBinding(); + _runApp(); } } @@ -244,7 +243,7 @@ class Catcher2 implements ReportModeAction { } } - void _initWidgetsBindingIfNeeded() { + void _initWidgetsBinding() { if (ensureInitialized) { WidgetsFlutterBinding.ensureInitialized(); } diff --git a/lib/handlers/http_handler.dart b/lib/handlers/http_handler.dart index aed2125..5334ad4 100644 --- a/lib/handlers/http_handler.dart +++ b/lib/handlers/http_handler.dart @@ -70,10 +70,12 @@ class HttpHandler extends ReportHandler { Response? response; _printLog('Calling: $endpointUri'); if (report.screenshot != null) { - final screenshotPath = report.screenshot?.path ?? ''; final formData = FormData.fromMap({ 'payload_json': json, - 'file': await MultipartFile.fromFile(screenshotPath), + 'file': MultipartFile.fromBytes( + await report.screenshot!.readAsBytes(), + filename: report.screenshot!.name, + ), }); response = await _dio.post( endpointUri.toString(), diff --git a/lib/handlers/sentry_handler.dart b/lib/handlers/sentry_handler.dart index aac6ac0..090ac6f 100644 --- a/lib/handlers/sentry_handler.dart +++ b/lib/handlers/sentry_handler.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:catcher_2/model/platform_type.dart'; import 'package:catcher_2/model/report.dart'; import 'package:catcher_2/model/report_handler.dart'; @@ -10,9 +8,9 @@ import 'package:sentry/sentry.dart'; class SentryHandler extends ReportHandler { SentryHandler( this.sentryClient, { + this.userContext, this.serverName = 'Catcher 2', this.loggerName = 'Catcher 2', - this.userContext, this.enableDeviceParameters = true, this.enableApplicationParameters = true, this.enableCustomParameters = true, @@ -23,12 +21,16 @@ class SentryHandler extends ReportHandler { /// Sentry Client instance final SentryClient sentryClient; - final String serverName; - final String loggerName; /// User data SentryUser? userContext; + /// The server name to send + final String serverName; + + /// The logger name to send + final String loggerName; + /// Enable device parameters to be generated by Catcher 2 final bool enableDeviceParameters; @@ -38,15 +40,15 @@ class SentryHandler extends ReportHandler { /// Enable custom parameters to be generated by Catcher 2 final bool enableCustomParameters; - /// Custom environment, if null, Catcher 2 will generate it + /// Enable additional logs printing + final bool printLogs; + + /// Custom environment; if `null`, Catcher 2 will generate it final String? customEnvironment; - /// Custom release, if null, Catcher 2 will generate it + /// Custom release; if `null`, Catcher 2 will generate it final String? customRelease; - /// Enable additional logs printing - final bool printLogs; - @override Future handle(Report report, BuildContext? context) async { try { @@ -70,12 +72,9 @@ class SentryHandler extends ReportHandler { // and the code relies on File from dart:io that does not work in web // either because we do not have access to the file system in web. SentryAttachment? screenshotAttachment; - File? screenshotFile; try { if (report.screenshot != null && !kIsWeb) { - final screenshotPath = report.screenshot!.path; - screenshotFile = File(screenshotPath); - final bytes = await screenshotFile.readAsBytes(); + final bytes = await report.screenshot!.readAsBytes(); screenshotAttachment = SentryAttachment.fromScreenshotData(bytes); _printLog('Created screenshot attachment'); } @@ -91,12 +90,6 @@ class SentryHandler extends ReportHandler { : null, ); - if (screenshotFile != null) { - // Cleanup screenshot file after submission to save space on device. - await screenshotFile.delete(); - _printLog('Screenshot file removed from device (cleanup)'); - } - _printLog('Logged to sentry!'); return true; } catch (exception, stackTrace) {