From 81fe95952fcf1cff512290571f494b6dd268859e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Tue, 12 Oct 2021 18:10:32 +0200 Subject: [PATCH 1/9] debug print integration --- CHANGELOG.md | 1 + dart/lib/src/protocol/breadcrumb.dart | 16 +++++++ flutter/lib/src/default_integrations.dart | 46 +++++++++++++++++++++ flutter/test/default_integrations_test.dart | 25 +++++++++++ 4 files changed, 88 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efeef18b76..6d6cf21f56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased * Feat: Add current route as transaction (#615) +* Feat: Add Breadcrumbs for Flutters `debugPrint` # 6.1.0-alpha.2 diff --git a/dart/lib/src/protocol/breadcrumb.dart b/dart/lib/src/protocol/breadcrumb.dart index 2e41b52d5f..032ac4928d 100644 --- a/dart/lib/src/protocol/breadcrumb.dart +++ b/dart/lib/src/protocol/breadcrumb.dart @@ -66,6 +66,22 @@ class Breadcrumb { ); } + factory Breadcrumb.console({ + String? message, + SentryLevel? level, + DateTime? timestamp, + Map? data, + }) { + return Breadcrumb( + message: message, + level: level ?? SentryLevel.debug, + category: 'console', + type: 'debug', + timestamp: timestamp, + data: data, + ); + } + /// Describes the breadcrumb. /// /// This field is optional and may be set to null. diff --git a/flutter/lib/src/default_integrations.dart b/flutter/lib/src/default_integrations.dart index 13e6c3c1af..43cadd4b34 100644 --- a/flutter/lib/src/default_integrations.dart +++ b/flutter/lib/src/default_integrations.dart @@ -484,3 +484,49 @@ class LoadReleaseIntegration extends Integration { .replaceAll('\u{0000}', ''); } } + +/// Integration which intercepts Flutters [debugPrint] method. +/// If this integration is added, all calls to [debugPrint] a redirected to +/// add a [Breadcrumb]. [debugPrint] is not outputting to the console anymore! +/// This integration fixes the issue described in +/// [#492](https://github.com/getsentry/sentry-dart/issues/492). +class DebugPrintIntegration extends Integration { + late DebugPrintCallback debugPrintBackup; + late Hub _hub; + late SentryFlutterOptions _options; + + @override + FutureOr call(Hub hub, SentryFlutterOptions options) { + _hub = hub; + _options = options; + debugPrintBackup = debugPrint; + + // We're simply replacing debugPrint here. The default implementation is a + // a throttling system which prints using Darts print method. It's basically + // a fire and forget method which completes sometime in the future. We can't + // observe when it's done. + // + // This makes it impossible to just disable adding print() breadcrumbs + // before debugPrint is called and re-enable it after debugPrint was called. + // See the docs for more information. + // https://api.flutter.dev/flutter/foundation/debugPrint.html + debugPrint = _debugPrint; + } + + @override + void close() { + debugPrint = debugPrintBackup; + } + + void _debugPrint(String? message, {int? wrapWidth}) { + if (message == null) { + _options.logger( + SentryLevel.debug, + 'debugPrint Integration received "null" as message. ' + 'The message is dropped.', + ); + return; + } + _hub.addBreadcrumb(Breadcrumb.console(message: message)); + } +} diff --git a/flutter/test/default_integrations_test.dart b/flutter/test/default_integrations_test.dart index 2f2be6e499..8f58772de5 100644 --- a/flutter/test/default_integrations_test.dart +++ b/flutter/test/default_integrations_test.dart @@ -420,6 +420,31 @@ void main() { expect(fixture.options.dist, isNull); }); }); + + test('$DebugPrintIntegration debugPrint adds a breadcrumb', () { + final integration = DebugPrintIntegration(); + integration.call(fixture.hub, fixture.options); + + debugPrint('Foo Bar'); + + final breadcrumb = verify( + fixture.hub.addBreadcrumb(captureAny), + ).captured.first as Breadcrumb; + + expect(breadcrumb.message, 'Foo Bar'); + }); + + test( + '$DebugPrintIntegration debugPrint does not add a breadcrumb after close', + () { + final integration = DebugPrintIntegration(); + integration.call(fixture.hub, fixture.options); + integration.close(); + + debugPrint('Foo Bar'); + + verifyNever(fixture.hub.addBreadcrumb(captureAny)); + }); } class Fixture { From 8f5e66f913ee9c3afff108ba02acf19bebca6794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Tue, 12 Oct 2021 18:16:14 +0200 Subject: [PATCH 2/9] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d6cf21f56..e6cd65e435 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Unreleased * Feat: Add current route as transaction (#615) -* Feat: Add Breadcrumbs for Flutters `debugPrint` +* Feat: Add Breadcrumbs for Flutters `debugPrint` (#618) # 6.1.0-alpha.2 From 29c71955affa96c31ea0daa3d44746b4793fb525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Wed, 13 Oct 2021 17:39:03 +0200 Subject: [PATCH 3/9] refactoring + close test --- flutter/lib/src/default_integrations.dart | 46 -------------- .../integrations/debug_print_integration.dart | 52 ++++++++++++++++ flutter/test/default_integrations_test.dart | 25 -------- .../debug_print_integration_test.dart | 62 +++++++++++++++++++ 4 files changed, 114 insertions(+), 71 deletions(-) create mode 100644 flutter/lib/src/integrations/debug_print_integration.dart create mode 100644 flutter/test/integrations/debug_print_integration_test.dart diff --git a/flutter/lib/src/default_integrations.dart b/flutter/lib/src/default_integrations.dart index 43cadd4b34..13e6c3c1af 100644 --- a/flutter/lib/src/default_integrations.dart +++ b/flutter/lib/src/default_integrations.dart @@ -484,49 +484,3 @@ class LoadReleaseIntegration extends Integration { .replaceAll('\u{0000}', ''); } } - -/// Integration which intercepts Flutters [debugPrint] method. -/// If this integration is added, all calls to [debugPrint] a redirected to -/// add a [Breadcrumb]. [debugPrint] is not outputting to the console anymore! -/// This integration fixes the issue described in -/// [#492](https://github.com/getsentry/sentry-dart/issues/492). -class DebugPrintIntegration extends Integration { - late DebugPrintCallback debugPrintBackup; - late Hub _hub; - late SentryFlutterOptions _options; - - @override - FutureOr call(Hub hub, SentryFlutterOptions options) { - _hub = hub; - _options = options; - debugPrintBackup = debugPrint; - - // We're simply replacing debugPrint here. The default implementation is a - // a throttling system which prints using Darts print method. It's basically - // a fire and forget method which completes sometime in the future. We can't - // observe when it's done. - // - // This makes it impossible to just disable adding print() breadcrumbs - // before debugPrint is called and re-enable it after debugPrint was called. - // See the docs for more information. - // https://api.flutter.dev/flutter/foundation/debugPrint.html - debugPrint = _debugPrint; - } - - @override - void close() { - debugPrint = debugPrintBackup; - } - - void _debugPrint(String? message, {int? wrapWidth}) { - if (message == null) { - _options.logger( - SentryLevel.debug, - 'debugPrint Integration received "null" as message. ' - 'The message is dropped.', - ); - return; - } - _hub.addBreadcrumb(Breadcrumb.console(message: message)); - } -} diff --git a/flutter/lib/src/integrations/debug_print_integration.dart b/flutter/lib/src/integrations/debug_print_integration.dart new file mode 100644 index 0000000000..484599e079 --- /dev/null +++ b/flutter/lib/src/integrations/debug_print_integration.dart @@ -0,0 +1,52 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:sentry/sentry.dart'; + +import '../sentry_flutter_options.dart'; + +/// Integration which intercepts Flutters [debugPrint] method. +/// If this integration is added, all calls to [debugPrint] a redirected to +/// add a [Breadcrumb]. [debugPrint] is not outputting to the console anymore! +/// This integration fixes the issue described in +/// [#492](https://github.com/getsentry/sentry-dart/issues/492). +class DebugPrintIntegration extends Integration { + late DebugPrintCallback _debugPrintBackup; + late Hub _hub; + late SentryFlutterOptions _options; + + @override + FutureOr call(Hub hub, SentryFlutterOptions options) { + _hub = hub; + _options = options; + _debugPrintBackup = debugPrint; + + // We're simply replacing debugPrint here. The default implementation is a + // a throttling system which prints using Darts print method. It's basically + // a fire and forget method which completes sometime in the future. We can't + // observe when it's done. + // + // This makes it impossible to just disable adding print() breadcrumbs + // before debugPrint is called and re-enable it after debugPrint was called. + // See the docs for more information. + // https://api.flutter.dev/flutter/foundation/debugPrint.html + debugPrint = _debugPrint; + } + + @override + void close() { + debugPrint = _debugPrintBackup; + } + + void _debugPrint(String? message, {int? wrapWidth}) { + if (message == null) { + _options.logger( + SentryLevel.debug, + 'debugPrint Integration received "null" as message. ' + 'The message is dropped.', + ); + return; + } + _hub.addBreadcrumb(Breadcrumb.console(message: message)); + } +} diff --git a/flutter/test/default_integrations_test.dart b/flutter/test/default_integrations_test.dart index 8f58772de5..2f2be6e499 100644 --- a/flutter/test/default_integrations_test.dart +++ b/flutter/test/default_integrations_test.dart @@ -420,31 +420,6 @@ void main() { expect(fixture.options.dist, isNull); }); }); - - test('$DebugPrintIntegration debugPrint adds a breadcrumb', () { - final integration = DebugPrintIntegration(); - integration.call(fixture.hub, fixture.options); - - debugPrint('Foo Bar'); - - final breadcrumb = verify( - fixture.hub.addBreadcrumb(captureAny), - ).captured.first as Breadcrumb; - - expect(breadcrumb.message, 'Foo Bar'); - }); - - test( - '$DebugPrintIntegration debugPrint does not add a breadcrumb after close', - () { - final integration = DebugPrintIntegration(); - integration.call(fixture.hub, fixture.options); - integration.close(); - - debugPrint('Foo Bar'); - - verifyNever(fixture.hub.addBreadcrumb(captureAny)); - }); } class Fixture { diff --git a/flutter/test/integrations/debug_print_integration_test.dart b/flutter/test/integrations/debug_print_integration_test.dart new file mode 100644 index 0000000000..1aaeb83b2b --- /dev/null +++ b/flutter/test/integrations/debug_print_integration_test.dart @@ -0,0 +1,62 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_flutter/src/integrations/debug_print_integration.dart'; + +import '../mocks.dart'; +import '../mocks.mocks.dart'; + +void main() { + late Fixture fixture; + + setUp(() { + fixture = Fixture(); + }); + + test('$DebugPrintIntegration: debugPrint adds a breadcrumb', () { + final integration = fixture.getSut(); + integration.call(fixture.hub, fixture.options); + + debugPrint('Foo Bar'); + + final breadcrumb = verify( + fixture.hub.addBreadcrumb(captureAny), + ).captured.first as Breadcrumb; + + expect(breadcrumb.message, 'Foo Bar'); + }); + + test( + '$DebugPrintIntegration: debugPrint does not add a breadcrumb after close', + () { + final integration = fixture.getSut(); + integration.call(fixture.hub, fixture.options); + integration.close(); + + debugPrint('Foo Bar'); + + verifyNever(fixture.hub.addBreadcrumb(captureAny)); + }); + + test( + '$DebugPrintIntegration: close changes debugPrint back to default implementation', + () { + final original = debugPrint; + + final integration = fixture.getSut(); + integration.call(fixture.hub, fixture.options); + integration.close(); + + expect(debugPrint, original); + }); +} + +class Fixture { + final hub = MockHub(); + final options = SentryFlutterOptions(dsn: fakeDsn); + + DebugPrintIntegration getSut() { + return DebugPrintIntegration(); + } +} From 1c178cd76c524b580a6063c06f2c00db8b2119cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Thu, 14 Oct 2021 18:21:29 +0200 Subject: [PATCH 4/9] disable in debug, enable when enablePrintBreadcrumbs --- .../integrations/debug_print_integration.dart | 6 +++ .../debug_print_integration_test.dart | 43 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/flutter/lib/src/integrations/debug_print_integration.dart b/flutter/lib/src/integrations/debug_print_integration.dart index 484599e079..4a4efb1176 100644 --- a/flutter/lib/src/integrations/debug_print_integration.dart +++ b/flutter/lib/src/integrations/debug_print_integration.dart @@ -21,6 +21,12 @@ class DebugPrintIntegration extends Integration { _options = options; _debugPrintBackup = debugPrint; + final isDebug = options.platformChecker.isDebugMode(); + final enablePrintBreadcrumbs = options.enablePrintBreadcrumbs; + if (isDebug || !enablePrintBreadcrumbs) { + return Future.value(); + } + // We're simply replacing debugPrint here. The default implementation is a // a throttling system which prints using Darts print method. It's basically // a fire and forget method which completes sometime in the future. We can't diff --git a/flutter/test/integrations/debug_print_integration_test.dart b/flutter/test/integrations/debug_print_integration_test.dart index 1aaeb83b2b..cbff05dc78 100644 --- a/flutter/test/integrations/debug_print_integration_test.dart +++ b/flutter/test/integrations/debug_print_integration_test.dart @@ -14,9 +14,13 @@ void main() { fixture = Fixture(); }); + tearDown(() { + debugPrint = debugPrintSynchronously; + }); + test('$DebugPrintIntegration: debugPrint adds a breadcrumb', () { final integration = fixture.getSut(); - integration.call(fixture.hub, fixture.options); + integration.call(fixture.hub, fixture.getOptions()); debugPrint('Foo Bar'); @@ -31,7 +35,7 @@ void main() { '$DebugPrintIntegration: debugPrint does not add a breadcrumb after close', () { final integration = fixture.getSut(); - integration.call(fixture.hub, fixture.options); + integration.call(fixture.hub, fixture.getOptions()); integration.close(); debugPrint('Foo Bar'); @@ -45,16 +49,47 @@ void main() { final original = debugPrint; final integration = fixture.getSut(); - integration.call(fixture.hub, fixture.options); + integration.call(fixture.hub, fixture.getOptions()); integration.close(); expect(debugPrint, original); }); + + test('$DebugPrintIntegration: disabled in debug builds', () { + final integration = fixture.getSut(); + integration.call(fixture.hub, fixture.getOptions(debug: true)); + + debugPrint('Foo Bar'); + + verifyNever(fixture.hub.addBreadcrumb(captureAny)); + }); + + test('$DebugPrintIntegration: disabled if enablePrintBreadcrumbs = false', + () { + final integration = fixture.getSut(); + integration.call( + fixture.hub, + fixture.getOptions(enablePrintBreadcrumbs: false), + ); + + debugPrint('Foo Bar'); + + verifyNever(fixture.hub.addBreadcrumb(captureAny)); + }); } class Fixture { final hub = MockHub(); - final options = SentryFlutterOptions(dsn: fakeDsn); + + SentryFlutterOptions getOptions({ + bool debug = false, + bool enablePrintBreadcrumbs = true, + }) { + return SentryFlutterOptions( + dsn: fakeDsn, + checker: MockPlatformChecker(isDebug: debug), + )..enablePrintBreadcrumbs = enablePrintBreadcrumbs; + } DebugPrintIntegration getSut() { return DebugPrintIntegration(); From b3ca15988625e000ca0340196f4d51233b2cb7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Thu, 14 Oct 2021 18:21:40 +0200 Subject: [PATCH 5/9] add as default integration --- flutter/lib/src/sentry_flutter.dart | 3 +++ flutter/test/sentry_flutter_test.dart | 2 ++ 2 files changed, 5 insertions(+) diff --git a/flutter/lib/src/sentry_flutter.dart b/flutter/lib/src/sentry_flutter.dart index d4fb00a048..b42893cf8b 100644 --- a/flutter/lib/src/sentry_flutter.dart +++ b/flutter/lib/src/sentry_flutter.dart @@ -5,6 +5,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry/sentry.dart'; import 'flutter_enricher_event_processor.dart'; +import 'integrations/debug_print_integration.dart'; import 'sentry_flutter_options.dart'; import 'default_integrations.dart'; @@ -107,6 +108,8 @@ mixin SentryFlutter { integrations.add(LoadAndroidImageListIntegration(channel)); } + integrations.add(DebugPrintIntegration()); + // This is an Integration because we want to execute it after all the // error handlers are in place. Calling a MethodChannel might result // in errors. diff --git a/flutter/test/sentry_flutter_test.dart b/flutter/test/sentry_flutter_test.dart index c92293ca3a..012f439eda 100644 --- a/flutter/test/sentry_flutter_test.dart +++ b/flutter/test/sentry_flutter_test.dart @@ -4,6 +4,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:sentry/sentry.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry/src/platform_checker.dart'; +import 'package:sentry_flutter/src/integrations/debug_print_integration.dart'; import 'package:sentry_flutter/src/version.dart'; import 'mocks.dart'; import 'sentry_flutter_util.dart'; @@ -13,6 +14,7 @@ import 'sentry_flutter_util.dart'; final platformAgnosticIntegrations = [ FlutterErrorIntegration, LoadReleaseIntegration, + DebugPrintIntegration, ]; // These should only be added to Android From f05d26989d959768326e4109fefe2a24c85605e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Thu, 14 Oct 2021 18:27:20 +0200 Subject: [PATCH 6/9] breadcrumb test --- dart/lib/src/protocol/breadcrumb.dart | 2 +- dart/test/protocol/breadcrumb_test.dart | 33 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/dart/lib/src/protocol/breadcrumb.dart b/dart/lib/src/protocol/breadcrumb.dart index 032ac4928d..e1ac8cd4fc 100644 --- a/dart/lib/src/protocol/breadcrumb.dart +++ b/dart/lib/src/protocol/breadcrumb.dart @@ -74,7 +74,7 @@ class Breadcrumb { }) { return Breadcrumb( message: message, - level: level ?? SentryLevel.debug, + level: level, category: 'console', type: 'debug', timestamp: timestamp, diff --git a/dart/test/protocol/breadcrumb_test.dart b/dart/test/protocol/breadcrumb_test.dart index 64adcbe381..890bc68296 100644 --- a/dart/test/protocol/breadcrumb_test.dart +++ b/dart/test/protocol/breadcrumb_test.dart @@ -128,4 +128,37 @@ void main() { 'type': 'http', }); }); + + test('Breadcrumb console ctor', () { + final breadcrumb = Breadcrumb.console( + message: 'Foo Bar', + ); + final json = breadcrumb.toJson(); + + expect(json, { + 'message': 'Foo Bar', + 'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp), + 'category': 'console', + 'type': 'debug', + 'level': 'info', + }); + }); + + test('extensive Breadcrumb console ctor', () { + final breadcrumb = Breadcrumb.console( + message: 'Foo Bar', + level: SentryLevel.error, + data: {'foo': 'bar'}, + ); + final json = breadcrumb.toJson(); + + expect(json, { + 'message': 'Foo Bar', + 'timestamp': formatDateAsIso8601WithMillisPrecision(breadcrumb.timestamp), + 'category': 'console', + 'type': 'debug', + 'level': 'error', + 'data': {'foo': 'bar'}, + }); + }); } From f2ecbffb2fa83fcd9713445609211daca962b967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Thu, 14 Oct 2021 18:28:31 +0200 Subject: [PATCH 7/9] use console breadcrumb in print integration --- dart/lib/src/default_integrations.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dart/lib/src/default_integrations.dart b/dart/lib/src/default_integrations.dart index 18cf0cb079..3138d2703d 100644 --- a/dart/lib/src/default_integrations.dart +++ b/dart/lib/src/default_integrations.dart @@ -67,11 +67,9 @@ class RunZonedGuardedIntegration extends Integration { _isPrinting = true; try { - hub.addBreadcrumb(Breadcrumb( + hub.addBreadcrumb(Breadcrumb.console( message: line, level: SentryLevel.debug, - category: 'console', - type: 'debug', )); parent.print(zone, line); From a78cc6627bbe4b99e9139483ebe002a08d0b1da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Thu, 14 Oct 2021 18:29:10 +0200 Subject: [PATCH 8/9] use debug level --- flutter/lib/src/integrations/debug_print_integration.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flutter/lib/src/integrations/debug_print_integration.dart b/flutter/lib/src/integrations/debug_print_integration.dart index 4a4efb1176..a2e6ba3e81 100644 --- a/flutter/lib/src/integrations/debug_print_integration.dart +++ b/flutter/lib/src/integrations/debug_print_integration.dart @@ -53,6 +53,9 @@ class DebugPrintIntegration extends Integration { ); return; } - _hub.addBreadcrumb(Breadcrumb.console(message: message)); + _hub.addBreadcrumb(Breadcrumb.console( + message: message, + level: SentryLevel.debug, + )); } } From 7c051fed6e17304185ab495eb8e2a68f27e23ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Ueko=CC=88tter?= Date: Fri, 15 Oct 2021 18:26:24 +0200 Subject: [PATCH 9/9] feedback --- .../lib/src/integrations/debug_print_integration.dart | 11 ++++++++--- .../integrations/debug_print_integration_test.dart | 9 +++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/flutter/lib/src/integrations/debug_print_integration.dart b/flutter/lib/src/integrations/debug_print_integration.dart index a2e6ba3e81..93142b9217 100644 --- a/flutter/lib/src/integrations/debug_print_integration.dart +++ b/flutter/lib/src/integrations/debug_print_integration.dart @@ -11,7 +11,7 @@ import '../sentry_flutter_options.dart'; /// This integration fixes the issue described in /// [#492](https://github.com/getsentry/sentry-dart/issues/492). class DebugPrintIntegration extends Integration { - late DebugPrintCallback _debugPrintBackup; + DebugPrintCallback? _debugPrintBackup; late Hub _hub; late SentryFlutterOptions _options; @@ -19,7 +19,6 @@ class DebugPrintIntegration extends Integration { FutureOr call(Hub hub, SentryFlutterOptions options) { _hub = hub; _options = options; - _debugPrintBackup = debugPrint; final isDebug = options.platformChecker.isDebugMode(); final enablePrintBreadcrumbs = options.enablePrintBreadcrumbs; @@ -27,6 +26,8 @@ class DebugPrintIntegration extends Integration { return Future.value(); } + _debugPrintBackup = debugPrint; + // We're simply replacing debugPrint here. The default implementation is a // a throttling system which prints using Darts print method. It's basically // a fire and forget method which completes sometime in the future. We can't @@ -37,11 +38,15 @@ class DebugPrintIntegration extends Integration { // See the docs for more information. // https://api.flutter.dev/flutter/foundation/debugPrint.html debugPrint = _debugPrint; + + options.sdk.addIntegration('debugPrintIntegration'); } @override void close() { - debugPrint = _debugPrintBackup; + if (_debugPrintBackup != null) { + debugPrint = _debugPrintBackup!; + } } void _debugPrint(String? message, {int? wrapWidth}) { diff --git a/flutter/test/integrations/debug_print_integration_test.dart b/flutter/test/integrations/debug_print_integration_test.dart index cbff05dc78..b7804abeeb 100644 --- a/flutter/test/integrations/debug_print_integration_test.dart +++ b/flutter/test/integrations/debug_print_integration_test.dart @@ -76,6 +76,15 @@ void main() { verifyNever(fixture.hub.addBreadcrumb(captureAny)); }); + + test( + '$DebugPrintIntegration: close works if debugPrintIntegration.call was not called', + () { + final integration = fixture.getSut(); + + // test is successful if no exception is thrown + expect(() => integration.close(), returnsNormally); + }); } class Fixture {