diff --git a/packages/stream_chat_v1/android/app/build.gradle b/packages/stream_chat_v1/android/app/build.gradle index 147d607..189df97 100644 --- a/packages/stream_chat_v1/android/app/build.gradle +++ b/packages/stream_chat_v1/android/app/build.gradle @@ -40,7 +40,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.example" - minSdkVersion 21 + minSdkVersion 22 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/packages/stream_chat_v1/lib/advanced_options_page.dart b/packages/stream_chat_v1/lib/advanced_options_page.dart index a42f200..facb9a0 100644 --- a/packages/stream_chat_v1/lib/advanced_options_page.dart +++ b/packages/stream_chat_v1/lib/advanced_options_page.dart @@ -294,10 +294,7 @@ class _AdvancedOptionsPageState extends State { ), ); - final client = StreamChatClient( - apiKey, - logLevel: Level.INFO, - )..chatPersistenceClient = chatPersistentClient; + final client = buildStreamChatClient(apiKey); try { await client.connectUser( diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart index fc4ed9b..3acb1a9 100644 --- a/packages/stream_chat_v1/lib/main.dart +++ b/packages/stream_chat_v1/lib/main.dart @@ -4,17 +4,16 @@ import 'package:example/choose_user_page.dart'; import 'package:example/home_page.dart'; import 'package:example/localizations.dart'; import 'package:example/splash_screen.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_localizations/stream_chat_localizations.dart'; import 'package:stream_chat_persistence/stream_chat_persistence.dart'; import 'package:streaming_shared_preferences/streaming_shared_preferences.dart'; -import 'app_config.dart'; import 'routes/app_routes.dart'; import 'routes/routes.dart'; @@ -23,8 +22,65 @@ final chatPersistentClient = StreamChatPersistenceClient( connectionMode: ConnectionMode.regular, ); +void sampleAppLogHandler(LogRecord record) async { + if (kDebugMode) StreamChatClient.defaultLogHandler(record); + + // report errors to sentry + if (record.error != null || record.stackTrace != null) { + await Sentry.captureException( + record.error, + stackTrace: record.stackTrace, + ); + } +} + +StreamChatClient buildStreamChatClient( + String apiKey, { + Level logLevel = Level.SEVERE, +}) { + return StreamChatClient( + apiKey, + logLevel: logLevel, + logHandlerFunction: sampleAppLogHandler, + )..chatPersistenceClient = chatPersistentClient; +} + void main() async { - runApp(MyApp()); + const sentryDsn = + 'https://6381ef88de4140db8f5e25ab37e0f08c@o1213503.ingest.sentry.io/6352870'; + + /// Captures errors reported by the Flutter framework. + FlutterError.onError = (FlutterErrorDetails details) { + if (kDebugMode) { + // In development mode, simply print to console. + FlutterError.dumpErrorToConsole(details); + } else { + // In production mode, report to the application zone to report to sentry. + Zone.current.handleUncaughtError(details.exception, details.stack!); + } + }; + + Future _reportError(dynamic error, StackTrace stackTrace) async { + // Print the exception to the console. + if (kDebugMode) { + // Print the full stacktrace in debug mode. + print(stackTrace); + return; + } else { + // Send the Exception and Stacktrace to sentry in Production mode. + await Sentry.captureException(error, stackTrace: stackTrace); + } + } + + runZonedGuarded( + () async { + await SentryFlutter.init( + (options) => options.dsn = sentryDsn, + ); + runApp(MyApp()); + }, + _reportError, + ); } class MyApp extends StatefulWidget { @@ -46,10 +102,7 @@ class _MyAppState extends State token = await secureStorage.read(key: kStreamToken); } - final client = StreamChatClient( - apiKey ?? kDefaultStreamApiKey, - logLevel: Level.SEVERE, - )..chatPersistenceClient = chatPersistentClient; + final client = buildStreamChatClient(apiKey ?? kStreamApiKey); if (userId != null && token != null) { await client.connectUser( diff --git a/packages/stream_chat_v1/pubspec.yaml b/packages/stream_chat_v1/pubspec.yaml index 1585c6b..6f9ccbc 100644 --- a/packages/stream_chat_v1/pubspec.yaml +++ b/packages/stream_chat_v1/pubspec.yaml @@ -33,6 +33,7 @@ dependencies: streaming_shared_preferences: ^2.0.0 lottie: ^1.2.1 collection: ^1.15.0 + sentry_flutter: ^6.5.0 dev_dependencies: flutter_launcher_icons: ^0.9.2 @@ -40,10 +41,7 @@ dev_dependencies: dependency_overrides: stream_chat: - git: - url: https://github.com/GetStream/stream-chat-flutter.git - ref: develop - path: packages/stream_chat + path: ../../../stream-chat-flutter/packages/stream_chat stream_chat_flutter_core: git: url: https://github.com/GetStream/stream-chat-flutter.git