From 6ac77d99042de2a1950f89b35972e3ee1116dc9f Mon Sep 17 00:00:00 2001 From: Remi Rousselet Date: Thu, 24 Feb 2022 17:18:13 +0100 Subject: [PATCH] feat(*): refactor error handling to preserve stack traces on platform exceptions (#8156) Co-authored-by: Mike Diarmid --- .../method_channel_document_reference.dart | 55 +++++++------- .../method_channel_firestore.dart | 51 +++++++------ .../method_channel/method_channel_query.dart | 26 ++++--- .../method_channel_write_batch.dart | 4 +- .../src/method_channel/utils/exception.dart | 9 ++- .../method_channel_https_callable.dart | 2 +- .../src/method_channel/utils/exception.dart | 23 +++--- .../method_channel/utils/exception_test.dart | 27 ++++--- .../method_channel_firebase_analytics.dart | 18 ++--- .../src/method_channel/utils/exception.dart | 15 ++-- .../src/method_channel/utils/exception.dart | 24 ++++--- ...od_channel_firebase_app_installations.dart | 35 ++++----- .../src/method_channel/utils/exception.dart | 23 +++--- .../method_channel_firebase_auth.dart | 72 +++++++++---------- .../method_channel/method_channel_user.dart | 52 +++++++------- .../src/method_channel/utils/exception.dart | 10 +-- .../utils_tests/exception_test.dart | 26 ++++--- .../firebase_core/lib/src/firebase.dart | 4 +- .../firebase_core/lib/src/internals.dart | 41 ++++++----- .../lib/src/interop_shimmer.dart | 1 - .../firebase_core/firebase_core/pubspec.yaml | 2 +- .../firebase_core/test/guard_test.dart | 69 ++++++++++++++++++ .../src/method_channel/utils/exception.dart | 24 ++++--- .../utils_tests/exception_test.dart | 25 +++---- .../method_channel_database.dart | 6 +- .../method_channel_database_reference.dart | 10 +-- .../method_channel_on_disconnect.dart | 8 +-- .../method_channel/method_channel_query.dart | 6 +- .../src/method_channel/utils/exception.dart | 15 ++-- ...method_channel_firebase_dynamic_links.dart | 18 +++-- .../src/method_channel/utils/exception.dart | 16 ++--- ...hod_channel_firebase_in_app_messaging.dart | 6 +- .../src/method_channel/utils/exception.dart | 13 ++-- .../method_channel_messaging.dart | 44 ++++++------ .../src/method_channel/utils/exception.dart | 19 +++-- ..._channel_firebase_ml_model_downloader.dart | 6 +- .../src/method_channel/utils/exception.dart | 27 ++++--- .../method_channel_firebase_performance.dart | 4 +- .../method_channel_http_metric.dart | 4 +- .../method_channel/method_channel_trace.dart | 4 +- .../src/method_channel/utils/exception.dart | 14 ++-- ...method_channel_firebase_remote_config.dart | 12 ++-- .../src/method_channel/utils/exception.dart | 9 ++- .../method_channel_firebase_storage.dart | 2 +- .../method_channel_reference.dart | 28 ++++---- .../method_channel/method_channel_task.dart | 14 ++-- .../src/method_channel/utils/exception.dart | 28 +++++--- 47 files changed, 548 insertions(+), 403 deletions(-) create mode 100644 packages/firebase_core/firebase_core/test/guard_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 8e5ffa12741c..bdb3874e7658 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -40,8 +40,8 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { }, }, ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -56,8 +56,8 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { 'data': data, }, ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -77,8 +77,8 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { ); return DocumentSnapshotPlatform(firestore, _pointer.path, data!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -89,8 +89,8 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { 'DocumentReference#delete', {'firestore': firestore, 'reference': this}, ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -111,24 +111,27 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { snapshotStream = MethodChannelFirebaseFirestore.documentSnapshotChannel(observerId!) .receiveBroadcastStream( - { - 'reference': this, - 'includeMetadataChanges': includeMetadataChanges, - }, - ).listen((snapshot) { - controller.add( - DocumentSnapshotPlatform( - firestore, - snapshot['path'], - { - 'data': snapshot['data'], - 'metadata': snapshot['metadata'], - }, - ), - ); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + { + 'reference': this, + 'includeMetadataChanges': includeMetadataChanges, + }, + ) + .handleError(convertPlatformException) + .listen( + (snapshot) { + controller.add( + DocumentSnapshotPlatform( + firestore, + snapshot['path'], + { + 'data': snapshot['data'], + 'metadata': snapshot['metadata'], + }, + ), + ); + }, + onError: controller.addError, + ); }, onCancel: () { snapshotStream?.cancel(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index 1c6fea34c81f..8935caff566a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -107,16 +107,20 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { FirebaseFirestorePlatform.instance, data!, ); - } catch (e) { + } catch (e, stack) { if (e.toString().contains('Named query has not been found')) { - throw FirebaseException( + Error.throwWithStackTrace( + FirebaseException( plugin: 'cloud_firestore', code: 'non-existent-named-query', - message: - 'Named query has not been found. Please check it has been loaded properly via loadBundle().'); + message: 'Named query has not been found. ' + 'Please check it has been loaded properly via loadBundle().', + ), + stack, + ); } - throw convertPlatformException(e); + convertPlatformException(e, stack); } } @@ -130,8 +134,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { .invokeMethod('Firestore#clearPersistence', { 'firestore': this, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -160,8 +164,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { .invokeMethod('Firestore#disableNetwork', { 'firestore': this, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -177,8 +181,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { .invokeMethod('Firestore#enableNetwork', { 'firestore': this, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -195,14 +199,15 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { snapshotStream = MethodChannelFirebaseFirestore.snapshotsInSyncChannel(observerId!) .receiveBroadcastStream( - { - 'firestore': this, - }, - ).listen((event) { - controller.add(null); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + { + 'firestore': this, + }, + ) + .handleError(convertPlatformException) + .listen( + (event) => controller.add(null), + onError: controller.addError, + ); }, onCancel: () { snapshotStream?.cancel(); @@ -306,8 +311,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { await channel.invokeMethod('Firestore#terminate', { 'firestore': this, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -318,8 +323,8 @@ class MethodChannelFirebaseFirestore extends FirebaseFirestorePlatform { 'Firestore#waitForPendingWrites', { 'firestore': this, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index cc41ea3eb236..08b9e23a28ba 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -106,8 +106,8 @@ class MethodChannelQuery extends QueryPlatform { ); return MethodChannelQuerySnapshot(firestore, data!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -145,15 +145,19 @@ class MethodChannelQuery extends QueryPlatform { snapshotStream = MethodChannelFirebaseFirestore.querySnapshotChannel(observerId!) .receiveBroadcastStream( - { - 'query': this, - 'includeMetadataChanges': includeMetadataChanges, - }, - ).listen((snapshot) { - controller.add(MethodChannelQuerySnapshot(firestore, snapshot)); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + { + 'query': this, + 'includeMetadataChanges': includeMetadataChanges, + }, + ) + .handleError(convertPlatformException) + .listen( + (snapshot) { + controller + .add(MethodChannelQuerySnapshot(firestore, snapshot)); + }, + onError: controller.addError, + ); }, onCancel: () { snapshotStream?.cancel(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index 8764013e4210..37c6dd17156e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -48,8 +48,8 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { 'firestore': _firestore, 'writes': _writes, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart index 235d91e8cb8b..7c87b0dff169 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart @@ -9,12 +9,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart index 678c7b0d57ae..3aec055febda 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/method_channel_https_callable.dart @@ -36,7 +36,7 @@ class MethodChannelHttpsCallable extends HttpsCallablePlatform { return result; } } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/utils/exception.dart index b4d759ddea56..b97fd057914a 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/lib/src/method_channel/utils/exception.dart @@ -11,12 +11,15 @@ import '../../../cloud_functions_platform_interface.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseFunctionsException] is returned. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseFunctionsException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseFunctionsException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseFunctionsException]. @@ -25,8 +28,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// the `details` of the exception exist. Firebase returns specific codes and /// messages which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseFunctionsException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -41,8 +45,9 @@ FirebaseException platformExceptionToFirebaseFunctionsException( } return FirebaseFunctionsException( - code: code, - message: message!, - details: additionalData, - stackTrace: stackTrace); + code: code, + message: message!, + details: additionalData, + stackTrace: stackTrace, + ); } diff --git a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart index 583b75734bd5..0af22be8f48e 100644 --- a/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart +++ b/packages/cloud_functions/cloud_functions_platform_interface/test/method_channel/utils/exception_test.dart @@ -17,8 +17,10 @@ void main() { test('should throw any exception', () async { AssertionError assertionError = AssertionError(); - expect(() => convertPlatformException(assertionError), - throwsA(isA())); + expect( + () => convertPlatformException(assertionError, StackTrace.empty), + throwsA(isA()), + ); }); test( @@ -30,11 +32,14 @@ void main() { ); expect( - convertPlatformException(platformException), + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( isA() .having((e) => e.code, 'code', 'unknown') .having((e) => e.message, 'message', testMessage) - .having((e) => e.details, 'details', isNull)); + .having((e) => e.details, 'details', isNull), + ), + ); }); test('should override code and message if provided to additional details', @@ -46,11 +51,14 @@ void main() { details: {'code': code, 'message': testMessage}); expect( - convertPlatformException(platformException), + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( isA() .having((e) => e.code, 'code', code) .having((e) => e.message, 'message', testMessage) - .having((e) => e.details, 'details', isNull)); + .having((e) => e.details, 'details', isNull), + ), + ); }); test('should provide additionalData as details', () async { @@ -60,7 +68,8 @@ void main() { details: {'additionalData': testAdditionalData}); expect( - convertPlatformException(platformException), + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( isA() .having((e) => e.code, 'code', 'unknown') .having((e) => e.message, 'message', testMessage) @@ -68,7 +77,9 @@ void main() { (e) => e.details, 'details', isA>() - .having((e) => e['foo'], 'additionalData', 'bar'))); + .having((e) => e['foo'], 'additionalData', 'bar')), + ), + ); }); }); } diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart index 717db1a3a8fa..de99635923b7 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/method_channel_firebase_analytics.dart @@ -50,7 +50,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { 'parameters': parameters, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -70,7 +70,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { }, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -84,7 +84,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { defaultParameters, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -98,7 +98,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { }, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -113,7 +113,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { {'userId': id}, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -132,7 +132,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { }, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -149,7 +149,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { 'value': value, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -158,7 +158,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { try { return channel.invokeMethod('Analytics#resetAnalyticsData'); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -172,7 +172,7 @@ class MethodChannelFirebaseAnalytics extends FirebaseAnalyticsPlatform { }); } } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/utils/exception.dart index e6ecf5698a5e..baca0aebb04b 100644 --- a/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_analytics/firebase_analytics_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,9 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, [ - StackTrace? stackTrace, -]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/utils/exception.dart index 2c88e2c963de..62235d8387b3 100644 --- a/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_app_check/firebase_app_check_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,13 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - // ignore: only_throw_errors - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -23,8 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -38,8 +41,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_app_check', - code: code, - message: message, - stackTrace: stackTrace); + plugin: 'firebase_app_check', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart index 1870c7611c2f..857f0da523b8 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/method_channel_firebase_app_installations.dart @@ -29,34 +29,23 @@ class MethodChannelFirebaseAppInstallations /// Creates a new [MethodChannelFirebaseAppInstallations] instance with an [app]. MethodChannelFirebaseAppInstallations({required FirebaseApp app}) : super(app) { - _idTokenChangesListeners[app.name] = StreamController.broadcast(); + final controller = _idTokenChangesListeners[app.name] = + StreamController.broadcast(); channel.invokeMethod( 'FirebaseInstallations#registerIdChangeListener', { 'appName': app.name, }).then((channelName) { final events = EventChannel(channelName!, channel.codec); - events.receiveBroadcastStream().listen((arguments) { - _handleIdChangedListener(app.name, arguments); - }, onError: (error, stackTrace) { - _handleIdChangedError(app.name, error, stackTrace); - }); + events + .receiveBroadcastStream() + .handleError(convertPlatformException) + .listen( + (Object? arguments) => controller.add((arguments as Map)['token']), + onError: controller.addError, + ); }); } - void _handleIdChangedError(String appName, Object error, - [StackTrace? stackTrace]) { - final StreamController controller = - _idTokenChangesListeners[appName]!; - controller.addError(convertPlatformException(error), stackTrace); - } - - /// Handle any incoming events from Event Channel and forward on to the user. - void _handleIdChangedListener( - String appName, Map arguments) { - final StreamController controller = - _idTokenChangesListeners[appName]!; - controller.add(arguments['token']); - } /// Internal stub class initializer. /// @@ -76,7 +65,7 @@ class MethodChannelFirebaseAppInstallations 'appName': app!.name, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -90,7 +79,7 @@ class MethodChannelFirebaseAppInstallations return id!; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -103,7 +92,7 @@ class MethodChannelFirebaseAppInstallations return id!; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/utils/exception.dart index adcb16c0ab30..471280d2f515 100644 --- a/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_app_installations/firebase_app_installations_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,8 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -37,8 +41,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_app_installations', - code: code, - message: message, - stackTrace: stackTrace); + plugin: 'firebase_app_installations', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart index a6c583c976b8..0a70979432ef 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_firebase_auth.dart @@ -197,8 +197,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { 'host': host, 'port': port, })); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -210,8 +210,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { _withChannelDefaults({ 'code': code, })); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -229,8 +229,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { operation: result['operation'], data: Map.from(result['data']), ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -243,8 +243,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { 'code': code, 'newPassword': newPassword, })); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -265,8 +265,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -281,8 +281,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { })))!; return List.from(data['providers']); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -320,8 +320,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { 'email': email, 'actionCodeSettings': actionCodeSettings?.asMap(), })); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -337,8 +337,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { 'email': email, 'actionCodeSettings': actionCodeSettings.asMap(), })); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -354,8 +354,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { })))!; this.languageCode = data['languageCode']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -396,8 +396,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { try { await channel.invokeMethod( 'Auth#setSettings', _withChannelDefaults(arguments)); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -419,8 +419,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -441,8 +441,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -461,8 +461,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -483,8 +483,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -505,8 +505,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -531,8 +531,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { 'Auth#signOut', _withChannelDefaults({})); currentUser = null; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -547,8 +547,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { })))!; return data['email']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -611,8 +611,8 @@ class MethodChannelFirebaseAuth extends FirebaseAuthPlatform { codeAutoRetrievalTimeout(verificationId); } }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart index 258fdd25e97c..81dbc5bd18b8 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/method_channel_user.dart @@ -32,8 +32,8 @@ class MethodChannelUser extends UserPlatform { 'User#delete', _withChannelDefaults({}), ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -51,8 +51,8 @@ class MethodChannelUser extends UserPlatform { )))!; return data['token']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -69,8 +69,8 @@ class MethodChannelUser extends UserPlatform { ))!; return IdTokenResult(data); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -93,8 +93,8 @@ class MethodChannelUser extends UserPlatform { auth.currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -117,8 +117,8 @@ class MethodChannelUser extends UserPlatform { auth.currentUser = userCredential.user; return userCredential; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -132,8 +132,8 @@ class MethodChannelUser extends UserPlatform { MethodChannelUser user = MethodChannelUser(auth, data); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -146,8 +146,8 @@ class MethodChannelUser extends UserPlatform { 'User#sendEmailVerification', _withChannelDefaults( {'actionCodeSettings': actionCodeSettings?.asMap()})); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -171,8 +171,8 @@ class MethodChannelUser extends UserPlatform { auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); return user!; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -191,8 +191,8 @@ class MethodChannelUser extends UserPlatform { MethodChannelUser user = MethodChannelUser(auth, data); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -211,8 +211,8 @@ class MethodChannelUser extends UserPlatform { MethodChannelUser user = MethodChannelUser(auth, data); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -231,8 +231,8 @@ class MethodChannelUser extends UserPlatform { MethodChannelUser user = MethodChannelUser(auth, data); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -251,8 +251,8 @@ class MethodChannelUser extends UserPlatform { MethodChannelUser user = MethodChannelUser(auth, data); auth.currentUser = user; auth.sendAuthChangesEvent(auth.app.name, user); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -270,8 +270,8 @@ class MethodChannelUser extends UserPlatform { 'actionCodeSettings': actionCodeSettings?.asMap(), }, )); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } } diff --git a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart index ab64bcca9452..d268bdfab28c 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/lib/src/method_channel/utils/exception.dart @@ -9,13 +9,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseAuthException] /// if it was intentionally caught on the native platform. -Object convertPlatformException(Object exception) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! PlatformException) { - // TODO(rrousselGit): Is this dead code? - return exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseAuthException(exception); + Error.throwWithStackTrace( + platformExceptionToFirebaseAuthException(exception), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseAuthException]. diff --git a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart index 30eaaf5695f0..8d00393f785a 100644 --- a/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart +++ b/packages/firebase_auth/firebase_auth_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart @@ -13,27 +13,25 @@ void main() { test('should throw any exception', () async { AssertionError assertionError = AssertionError(); - try { - throw convertPlatformException(assertionError); - } on FirebaseAuthException catch (_) { - fail('should have thrown the original exception'); - } catch (_) { - return; - } + expect( + () => convertPlatformException(assertionError, StackTrace.empty), + throwsA(assertionError), + ); }); test('should catch a [PlatformException] and throw a [FirebaseException]', () async { PlatformException platformException = PlatformException(code: 'UNKNOWN'); - try { - throw convertPlatformException(platformException); - } on FirebaseAuthException catch (_) { - return; - } catch (_) { - fail('should have thrown an FirebaseAuthException'); - } + + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA().having((e) => e.code, 'code', 'unknown'), + ), + ); }); }); + group('platformExceptionToFirebaseAuthException()', () { test('sets code to default value', () { AuthCredential authCredential = const AuthCredential( diff --git a/packages/firebase_core/firebase_core/lib/src/firebase.dart b/packages/firebase_core/firebase_core/lib/src/firebase.dart index 4c9a9ef93e14..2e006da4b679 100644 --- a/packages/firebase_core/firebase_core/lib/src/firebase.dart +++ b/packages/firebase_core/firebase_core/lib/src/firebase.dart @@ -25,9 +25,7 @@ class Firebase { /// Returns a list of all [FirebaseApp] instances that have been created. static List get apps { - return _delegate.apps - .map((app) => FirebaseApp._(app)) - .toList(growable: false); + return _delegate.apps.map(FirebaseApp._).toList(growable: false); } /// Initializes a new [FirebaseApp] instance by [name] and [options] and returns diff --git a/packages/firebase_core/firebase_core/lib/src/internals.dart b/packages/firebase_core/firebase_core/lib/src/internals.dart index e8059356d2ee..2969fb8b9873 100644 --- a/packages/firebase_core/firebase_core/lib/src/internals.dart +++ b/packages/firebase_core/firebase_core/lib/src/internals.dart @@ -88,38 +88,47 @@ R guardWebExceptions( if (value is Future) { return value.catchError( - (err) => throw _mapException( - err, - plugin: plugin, - codeParser: codeParser, - messageParser: messageParser, + (err, stack) => Error.throwWithStackTrace( + _mapException( + err, + plugin: plugin, + codeParser: codeParser, + messageParser: messageParser, + ), + stack, ), test: _testException, ) as R; } else if (value is Stream) { return value.handleError( - (err) => throw _mapException( - err, - plugin: plugin, - codeParser: codeParser, - messageParser: messageParser, + (err, stack) => Error.throwWithStackTrace( + _mapException( + err, + plugin: plugin, + codeParser: codeParser, + messageParser: messageParser, + ), + stack, ), test: _testException, ) as R; } return value; - } catch (error) { + } catch (error, stack) { if (!_testException(error)) { // Make sure to preserve the stacktrace rethrow; } - throw _mapException( - error, - plugin: plugin, - codeParser: codeParser, - messageParser: messageParser, + Error.throwWithStackTrace( + _mapException( + error, + plugin: plugin, + codeParser: codeParser, + messageParser: messageParser, + ), + stack, ); } } diff --git a/packages/firebase_core/firebase_core/lib/src/interop_shimmer.dart b/packages/firebase_core/firebase_core/lib/src/interop_shimmer.dart index 57fe6a079e6a..f870762ba4f9 100644 --- a/packages/firebase_core/firebase_core/lib/src/interop_shimmer.dart +++ b/packages/firebase_core/firebase_core/lib/src/interop_shimmer.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // A library that mimicks package:firebase_core_web/firebase_core_web_interop.dart // for platforms that do not target dart2js diff --git a/packages/firebase_core/firebase_core/pubspec.yaml b/packages/firebase_core/firebase_core/pubspec.yaml index e12746f406f2..53bc1f999421 100644 --- a/packages/firebase_core/firebase_core/pubspec.yaml +++ b/packages/firebase_core/firebase_core/pubspec.yaml @@ -9,7 +9,7 @@ false_secrets: - example/** environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.16.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" dependencies: diff --git a/packages/firebase_core/firebase_core/test/guard_test.dart b/packages/firebase_core/firebase_core/test/guard_test.dart new file mode 100644 index 000000000000..75202f60bcc0 --- /dev/null +++ b/packages/firebase_core/firebase_core/test/guard_test.dart @@ -0,0 +1,69 @@ +import 'package:firebase_core/src/internals.dart'; +import 'package:firebase_core/src/interop_shimmer.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('guardWebException', () { + test('preserves stacktrace on futures that fail with FirebaseError', + () async { + final current = StackTrace.current; + try { + await guardWebExceptions( + () => Future.error(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ); + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }); + + test('preserves stacktrace on streams that fail with FirebaseError', + () async { + final current = StackTrace.current; + try { + await guardWebExceptions( + () => Stream.error(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ).first; + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }); + + test('preserves stacktrace on functions that throw a FirebaseError', + () async { + final current = StackTrace.current; + try { + guardWebExceptions( + () => Error.throwWithStackTrace(_FirebaseError(), current), + plugin: 'test', + codeParser: (c) => c, + ); + fail('dead code'); + } catch (err, stack) { + expect(stack, current); + } + }); + }); +} + +class _FirebaseError implements FirebaseError { + @override + String get code => ''; + + @override + String get message => ''; + + @override + String get name => ''; + + @override + Object get serverResponse => ''; + + @override + String get stack => ''; +} diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/utils/exception.dart index 8e803f671cb3..90eb6e6748fb 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,13 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - // ignore: only_throw_errors - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -23,8 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -38,8 +41,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_crashlytics', - code: code, - message: message, - stackTrace: stackTrace); + plugin: 'firebase_crashlytics', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart index c208f007db5c..0c1164f31c1f 100644 --- a/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart +++ b/packages/firebase_crashlytics/firebase_crashlytics_platform_interface/test/method_channel_tests/utils_tests/exception_test.dart @@ -13,25 +13,22 @@ void main() { test('should throw any exception', () async { AssertionError assertionError = AssertionError(); - try { - throw convertPlatformException(assertionError); - } on FirebaseException catch (_) { - fail('should have thrown the original exception'); - } catch (_) { - return; - } + expect( + () => convertPlatformException(assertionError, StackTrace.empty), + throwsA(assertionError), + ); }); test('should catch a [PlatformException] and throw a [FirebaseException]', () async { PlatformException platformException = PlatformException(code: 'UNKNOWN'); - try { - throw convertPlatformException(platformException); - } on FirebaseException catch (_) { - return; - } catch (_) { - fail('should have thrown an FirebaseCrashlyticsException'); - } + + expect( + () => convertPlatformException(platformException, StackTrace.empty), + throwsA( + isA().having((e) => e.code, 'code', 'unknown'), + ), + ); }); }); } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart index 74162775bc3a..efd683da09ec 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database.dart @@ -143,7 +143,7 @@ class MethodChannelDatabase extends DatabasePlatform { getChannelArguments(), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -157,7 +157,7 @@ class MethodChannelDatabase extends DatabasePlatform { getChannelArguments(), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -179,7 +179,7 @@ class MethodChannelDatabase extends DatabasePlatform { getChannelArguments(), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart index 03768a7c5d6d..2d3f0ed9d3b7 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_database_reference.dart @@ -83,7 +83,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -99,7 +99,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -114,7 +114,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -129,7 +129,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -173,7 +173,7 @@ class MethodChannelDatabaseReference extends MethodChannelQuery Map.from(result!['snapshot']), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } finally { handlers.remove(key); handlerErrors.remove(key); diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart index 5ba4120173f9..7f174731a7c6 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_on_disconnect.dart @@ -27,7 +27,7 @@ class MethodChannelOnDisconnect extends OnDisconnectPlatform { }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -45,7 +45,7 @@ class MethodChannelOnDisconnect extends OnDisconnectPlatform { ), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -60,7 +60,7 @@ class MethodChannelOnDisconnect extends OnDisconnectPlatform { database.getChannelArguments({'path': ref.path}), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -75,7 +75,7 @@ class MethodChannelOnDisconnect extends OnDisconnectPlatform { }), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart index 681d1b943c7f..662731b0261f 100755 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -62,7 +62,7 @@ class MethodChannelQuery extends QueryPlatform { MethodChannelDatabaseEvent(ref, Map.from(event)), ) .handleError( - (e, s) => throw convertPlatformException(e, s), + convertPlatformException, test: (err) => err is PlatformException, ); } @@ -83,7 +83,7 @@ class MethodChannelQuery extends QueryPlatform { Map.from(result!['snapshot']), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -110,7 +110,7 @@ class MethodChannelQuery extends QueryPlatform { ), ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/utils/exception.dart index dc7fbeab7bbb..565b6a017609 100644 --- a/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_database/firebase_database_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,9 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, [ - StackTrace? stackTrace, -]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 9a94de90d5d4..1ed18a24bbde 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -32,9 +32,13 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } break; case 'FirebaseDynamicLink#onLinkError': - Map error = - Map.from(call.arguments); - _onLinkController.addError(convertPlatformException(error)); + try { + Map error = + Map.from(call.arguments); + convertPlatformException(error, StackTrace.current); + } catch (err, stack) { + _onLinkController.addError(err, stack); + } break; default: throw UnimplementedError('${call.method} has not been implemented'); @@ -114,7 +118,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return _getPendingDynamicLinkDataFromMap(linkData); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -129,7 +133,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return _getPendingDynamicLinkDataFromMap(linkData); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -149,7 +153,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return Uri.parse(url!); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -181,7 +185,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { : null, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart index a928e64e7864..d58916c919ce 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,15 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException( - Object exception, [ - StackTrace? stackTrace, -]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -25,9 +25,9 @@ Exception convertPlatformException( /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, [ + PlatformException platformException, StackTrace? stackTrace, -]) { +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/method_channel_firebase_in_app_messaging.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/method_channel_firebase_in_app_messaging.dart index 2b4a43e80a8e..2f6d7c71742f 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/method_channel_firebase_in_app_messaging.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/method_channel_firebase_in_app_messaging.dart @@ -43,7 +43,7 @@ class MethodChannelFirebaseInAppMessaging 'eventName': eventName, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -56,7 +56,7 @@ class MethodChannelFirebaseInAppMessaging 'suppress': suppress, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -70,7 +70,7 @@ class MethodChannelFirebaseInAppMessaging 'enabled': enabled, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } } diff --git a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/utils/exception.dart index b1010a3afcf1..6bcc3f8b0d53 100644 --- a/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_in_app_messaging/firebase_in_app_messaging_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,9 +25,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// the `details` of the exception exist. Firebase returns specific codes and /// messages which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, [ + PlatformException platformException, StackTrace? stackTrace, -]) { +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart index 7b1bde5639db..23ebcbec3c1a 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/method_channel_messaging.dart @@ -160,8 +160,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { } return RemoteMessage.fromMap(remoteMessageMap); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -190,8 +190,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { try { await channel .invokeMapMethod('Messaging#deleteToken', {'appName': app.name}); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -209,8 +209,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { }); return data?['token']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -225,8 +225,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { }); return data?['token']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -245,8 +245,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { }); return convertToNotificationSettings(response!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -282,8 +282,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { }); return convertToNotificationSettings(response!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -297,8 +297,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { }); _autoInitEnabled = data?['isAutoInitEnabled'] as bool; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -326,8 +326,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { 'badge': badge, 'sound': sound, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -355,8 +355,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { 'messageType': messageType, 'ttl': ttl, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -367,8 +367,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { 'appName': app.name, 'topic': topic, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -379,8 +379,8 @@ class MethodChannelFirebaseMessaging extends FirebaseMessagingPlatform { 'appName': app.name, 'topic': topic, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } } diff --git a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/utils/exception.dart index 29e89a99ac6c..970d7c7b0280 100644 --- a/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_messaging/firebase_messaging_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Exception convertPlatformException(Object exception) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,7 +25,9 @@ Exception convertPlatformException(Object exception) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -36,5 +41,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_messaging', code: code, message: message); + plugin: 'firebase_messaging', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart index baddfe002f35..3251b38b2e03 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/method_channel_firebase_ml_model_downloader.dart @@ -57,7 +57,7 @@ class MethodChannelFirebaseModelDownloader return _resultToFirebaseCustomModel(result!); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -71,7 +71,7 @@ class MethodChannelFirebaseModelDownloader return result!.map(_resultToFirebaseCustomModel).toList(growable: false); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -84,7 +84,7 @@ class MethodChannelFirebaseModelDownloader 'modelName': modelName, }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart index 357eb0f7f324..78cfb28a18e1 100644 --- a/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_ml_model_downloader/firebase_ml_model_downloader_platform_interface/lib/src/method_channel/utils/exception.dart @@ -10,13 +10,18 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(dynamic exception, - [StackTrace? stackTrace]) { +Never convertPlatformException( + dynamic exception, + StackTrace stackTrace, +) { if (exception is! Exception || exception is! PlatformException) { - return exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -25,8 +30,9 @@ Exception convertPlatformException(dynamic exception, /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -40,8 +46,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_ml_model_downloader', - code: code, - message: message, - stackTrace: stackTrace); + plugin: 'firebase_ml_model_downloader', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart index 03856a5e1b0b..72ba660aea10 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_firebase_performance.dart @@ -57,7 +57,7 @@ class MethodChannelFirebasePerformance extends FirebasePerformancePlatform { ); return isPerformanceCollectionEnabled!; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -69,7 +69,7 @@ class MethodChannelFirebasePerformance extends FirebasePerformancePlatform { {'handle': _handle, 'enable': enabled}, ); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart index 0ffb39893d1c..17a4d7dae520 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_http_metric.dart @@ -80,7 +80,7 @@ class MethodChannelHttpMetric extends HttpMetricPlatform { ); _hasStarted = true; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -104,7 +104,7 @@ class MethodChannelHttpMetric extends HttpMetricPlatform { ); _hasStopped = true; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart index 6c3ce4f8f0c5..7f80a961698c 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/method_channel_trace.dart @@ -42,7 +42,7 @@ class MethodChannelTrace extends TracePlatform { ); _hasStarted = true; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } @@ -61,7 +61,7 @@ class MethodChannelTrace extends TracePlatform { ); _hasStopped = true; } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/utils/exception.dart index 6e9577f2fda2..5a2fcc387c03 100644 --- a/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_performance/firebase_performance_platform_interface/lib/src/method_channel/utils/exception.dart @@ -7,13 +7,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - // ignore: only_throw_errors - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -22,9 +24,9 @@ Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, [ + PlatformException platformException, StackTrace? stackTrace, -]) { +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart index b1a11431c606..e07d8d9ccce1 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/method_channel_firebase_remote_config.dart @@ -108,7 +108,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { 'appName': app.name, }); } catch (exception, stackTrace) { - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } @@ -122,7 +122,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { await _updateConfigParameters(); return configChanged!; } catch (exception, stackTrace) { - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } @@ -136,7 +136,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { } catch (exception, stackTrace) { // Ensure that fetch status is updated. await _updateConfigProperties(); - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } @@ -153,7 +153,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { } catch (exception, stackTrace) { // Ensure that fetch status is updated. await _updateConfigProperties(); - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } @@ -216,7 +216,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { }); await _updateConfigProperties(); } catch (exception, stackTrace) { - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } @@ -229,7 +229,7 @@ class MethodChannelFirebaseRemoteConfig extends FirebaseRemoteConfigPlatform { }); await _updateConfigParameters(); } catch (exception, stackTrace) { - throw convertPlatformException(exception, stackTrace); + convertPlatformException(exception, stackTrace); } } diff --git a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart index f5655956b7c3..d31524913911 100644 --- a/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_remote_config/firebase_remote_config_platform_interface/lib/src/method_channel/utils/exception.dart @@ -4,14 +4,13 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Exception convertPlatformException(Object exception, [StackTrace? stackTrace]) { +Never convertPlatformException(Object exception, StackTrace stackTrace) { if (exception is! Exception || exception is! PlatformException) { - // ignore: only_throw_errors - throw exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException( - exception, + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), stackTrace, ); } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart index 03b6908c86bd..650fa14f7e5f 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_firebase_storage.dart @@ -159,7 +159,7 @@ class MethodChannelFirebaseStorage extends FirebaseStoragePlatform { 'port': emulatorPort }); } catch (e, s) { - throw convertPlatformException(e, s); + convertPlatformException(e, s); } } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart index aafc9b1ca534..88cecaf5b3fb 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_reference.dart @@ -34,8 +34,8 @@ class MethodChannelReference extends ReferencePlatform { 'port': storage.emulatorPort, 'path': fullPath, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -56,8 +56,8 @@ class MethodChannelReference extends ReferencePlatform { }); return data!['downloadURL']; - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -78,8 +78,8 @@ class MethodChannelReference extends ReferencePlatform { }); return FullMetadata(data!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -108,8 +108,8 @@ class MethodChannelReference extends ReferencePlatform { items: List.from(data['items']), prefixes: List.from(data['prefixes']), ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -134,8 +134,8 @@ class MethodChannelReference extends ReferencePlatform { items: List.from(data['items']), prefixes: List.from(data['prefixes']), ); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -154,8 +154,8 @@ class MethodChannelReference extends ReferencePlatform { 'path': fullPath, 'maxSize': maxSize, }); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } @@ -209,8 +209,8 @@ class MethodChannelReference extends ReferencePlatform { }); return FullMetadata(data!); - } catch (e) { - throw convertPlatformException(e); + } catch (e, stack) { + convertPlatformException(e, stack); } } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart index f14cb6908789..720696af4e4b 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart @@ -89,7 +89,7 @@ abstract class MethodChannelTask extends TaskPlatform { Object? _exception; - StackTrace? _stackTrace; + late StackTrace _stackTrace; bool _didComplete = false; @@ -147,8 +147,8 @@ abstract class MethodChannelTask extends TaskPlatform { Map.from(data['snapshot'])); } return success; - } catch (e) { - return catchFuturePlatformException(e); + } catch (e, stack) { + return catchFuturePlatformException(e, stack); } } @@ -170,8 +170,8 @@ abstract class MethodChannelTask extends TaskPlatform { Map.from(data['snapshot'])); } return success; - } catch (e) { - return catchFuturePlatformException(e); + } catch (e, stack) { + return catchFuturePlatformException(e, stack); } } @@ -193,8 +193,8 @@ abstract class MethodChannelTask extends TaskPlatform { Map.from(data['snapshot'])); } return success; - } catch (e) { - return catchFuturePlatformException(e); + } catch (e, stack) { + return catchFuturePlatformException(e, stack); } } } diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart index 1442cebb5e6e..bbaf9b7d84d2 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/utils/exception.dart @@ -11,25 +11,34 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(dynamic exception, - [StackTrace? stackTrace]) { +Never convertPlatformException( + dynamic exception, + StackTrace stackTrace, +) { if (exception is! Exception || exception is! PlatformException) { - return exception; + Error.throwWithStackTrace(exception, stackTrace); } - return platformExceptionToFirebaseException(exception, stackTrace); + Error.throwWithStackTrace( + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Catches a [PlatformException] and converts it into a [FirebaseException] if /// it was intentionally caught on the native platform. -Future catchFuturePlatformException(Object exception, - [StackTrace? stackTrace]) { +Future catchFuturePlatformException( + Object exception, + StackTrace stackTrace, +) { if (exception is! Exception || exception is! PlatformException) { return Future.error(exception, stackTrace); } return Future.error( - platformExceptionToFirebaseException(exception, stackTrace)); + platformExceptionToFirebaseException(exception, stackTrace), + stackTrace, + ); } /// Converts a [PlatformException] into a [FirebaseException]. @@ -38,8 +47,9 @@ Future catchFuturePlatformException(Object exception, /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, + StackTrace stackTrace, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null;