TF-4136 Fix duplicate Executor instance creation.
This commit is contained in:
@@ -1056,6 +1056,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.8.0"
|
version: "9.8.0"
|
||||||
|
sentry_dio:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sentry_dio
|
||||||
|
sha256: bee438fd790c534da77f0a6c9cd04c54c818184b8a54bbe7d916489c8aad56a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.8.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export 'utils/html/html_utils.dart';
|
|||||||
export 'utils/web_link_generator.dart';
|
export 'utils/web_link_generator.dart';
|
||||||
export 'utils/sentry/sentry_manager.dart';
|
export 'utils/sentry/sentry_manager.dart';
|
||||||
export 'utils/config/env_loader.dart';
|
export 'utils/config/env_loader.dart';
|
||||||
|
export 'utils/sentry/sentry_dio_helper.dart';
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
export 'presentation/views/text/slogan_builder.dart';
|
export 'presentation/views/text/slogan_builder.dart';
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class ApplicationManager {
|
|||||||
_versionCache = null;
|
_versionCache = null;
|
||||||
_cachedWebUserAgent = null;
|
_cachedWebUserAgent = null;
|
||||||
_cachedMobileUserAgent = null;
|
_cachedMobileUserAgent = null;
|
||||||
|
_isMobileUserAgentInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PackageInfo> getPackageInfo() async {
|
Future<PackageInfo> getPackageInfo() async {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class EnvLoader {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logWarning('EnvLoader::loadFcmConfigFileToEnv: Exception = $e');
|
logWarning('EnvLoader::loadFcmConfigFileToEnv: Exception = $e');
|
||||||
|
// FCM config is optional; reload base config to restore dotenv.env state
|
||||||
await onCallBack?.call();
|
await onCallBack?.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class SentryConfig {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/// Load configuration from an env file.
|
/// Load configuration from an env file.
|
||||||
static Future<SentryConfig> load() async {
|
static Future<SentryConfig?> load() async {
|
||||||
await EnvLoader.loadConfigFromEnv();
|
await EnvLoader.loadConfigFromEnv();
|
||||||
|
|
||||||
final sentryAvailable = dotenv.get('SENTRY_ENABLED', fallback: 'false');
|
final sentryAvailable = dotenv.get('SENTRY_ENABLED', fallback: 'false');
|
||||||
@@ -54,12 +54,10 @@ class SentryConfig {
|
|||||||
final sentryDSN = dotenv.get('SENTRY_DSN', fallback: '');
|
final sentryDSN = dotenv.get('SENTRY_DSN', fallback: '');
|
||||||
final sentryEnvironment = dotenv.get('SENTRY_ENVIRONMENT', fallback: '');
|
final sentryEnvironment = dotenv.get('SENTRY_ENVIRONMENT', fallback: '');
|
||||||
|
|
||||||
if (!isAvailable) {
|
if (!isAvailable ||
|
||||||
throw Exception('Sentry is not available');
|
sentryDSN.trim().isEmpty ||
|
||||||
}
|
sentryEnvironment.trim().isEmpty) {
|
||||||
|
return null;
|
||||||
if (sentryDSN.trim().isEmpty || sentryEnvironment.trim().isEmpty) {
|
|
||||||
throw Exception('Sentry configuration is missing');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final appVersion = await ApplicationManager().getAppVersion();
|
final appVersion = await ApplicationManager().getAppVersion();
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:core/utils/sentry/sentry_manager.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:sentry_dio/sentry_dio.dart';
|
||||||
|
|
||||||
|
class SentryDioHelper {
|
||||||
|
static void addIfAvailable(Dio dio) {
|
||||||
|
if (!SentryManager.instance.isSentryAvailable) return;
|
||||||
|
|
||||||
|
final alreadyHasSentry = dio.interceptors.any(
|
||||||
|
(i) => i.runtimeType.toString().contains('FailedRequestInterceptor'));
|
||||||
|
if (!alreadyHasSentry) {
|
||||||
|
dio.addSentry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,14 +11,19 @@ class SentryInitializer {
|
|||||||
'x-auth',
|
'x-auth',
|
||||||
'x-token',
|
'x-token',
|
||||||
'api-key',
|
'api-key',
|
||||||
|
'x-api-key',
|
||||||
'apikey',
|
'apikey',
|
||||||
'secret',
|
'secret',
|
||||||
'bearer',
|
'bearer',
|
||||||
|
'session',
|
||||||
|
'password',
|
||||||
];
|
];
|
||||||
|
|
||||||
static Future<bool> init(FutureOr<void> Function() appRunner) async {
|
static Future<bool> init(FutureOr<void> Function() appRunner) async {
|
||||||
final config = await SentryConfig.load();
|
final config = await SentryConfig.load();
|
||||||
|
|
||||||
|
if (config == null) return false;
|
||||||
|
|
||||||
await SentryFlutter.init(
|
await SentryFlutter.init(
|
||||||
(options) {
|
(options) {
|
||||||
options.dsn = config.dsn;
|
options.dsn = config.dsn;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class SentryManager {
|
|||||||
try {
|
try {
|
||||||
if (_isSentryAvailable) {
|
if (_isSentryAvailable) {
|
||||||
log('[SentryManager] Already initialized, skipping');
|
log('[SentryManager] Already initialized, skipping');
|
||||||
|
await appRunner();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_isSentryAvailable = await SentryInitializer.init(appRunner);
|
_isSentryAvailable = await SentryInitializer.init(appRunner);
|
||||||
|
|||||||
@@ -1009,6 +1009,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.8.0"
|
version: "9.8.0"
|
||||||
|
sentry_dio:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: sentry_dio
|
||||||
|
sha256: bee438fd790c534da77f0a6c9cd04c54c818184b8a54bbe7d916489c8aad56a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.8.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ dependencies:
|
|||||||
|
|
||||||
sentry_flutter: 9.8.0
|
sentry_flutter: 9.8.0
|
||||||
|
|
||||||
|
sentry_dio: 9.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/http/http_client.dart';
|
import 'package:jmap_dart_client/http/http_client.dart';
|
||||||
import 'package:sentry_dio/sentry_dio.dart';
|
|
||||||
import 'package:tmail_ui_user/features/contact/data/network/contact_api.dart';
|
import 'package:tmail_ui_user/features/contact/data/network/contact_api.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart';
|
import 'package:tmail_ui_user/features/email/data/network/mdn_api.dart';
|
||||||
@@ -102,14 +101,7 @@ class NetworkBindings extends Bindings {
|
|||||||
if (BuildUtils.isDebugMode) {
|
if (BuildUtils.isDebugMode) {
|
||||||
dio.interceptors.add(LogInterceptor(requestBody: true));
|
dio.interceptors.add(LogInterceptor(requestBody: true));
|
||||||
}
|
}
|
||||||
if (SentryManager.instance.isSentryAvailable) {
|
SentryDioHelper.addIfAvailable(dio);
|
||||||
// Guard against duplicate Sentry interceptor registration
|
|
||||||
final alreadyHasSentry = dio.interceptors
|
|
||||||
.any((i) => i.runtimeType.toString().contains('Sentry'));
|
|
||||||
if (!alreadyHasSentry) {
|
|
||||||
dio.addSentry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingApi() {
|
void _bindingApi() {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:flutter_appauth/flutter_appauth.dart';
|
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/http/http_client.dart';
|
import 'package:jmap_dart_client/http/http_client.dart';
|
||||||
import 'package:sentry_dio/sentry_dio.dart';
|
|
||||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||||
import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart';
|
import 'package:tmail_ui_user/features/login/data/local/account_cache_manager.dart';
|
||||||
@@ -53,6 +52,7 @@ class NetworkIsolateBindings extends Bindings {
|
|||||||
|
|
||||||
void _bindingInterceptors() {
|
void _bindingInterceptors() {
|
||||||
final dio = Get.find<Dio>(tag: BindingTag.isolateTag);
|
final dio = Get.find<Dio>(tag: BindingTag.isolateTag);
|
||||||
|
Get.put(DynamicUrlInterceptors());
|
||||||
final authorizationInterceptors = AuthorizationInterceptors(
|
final authorizationInterceptors = AuthorizationInterceptors(
|
||||||
dio,
|
dio,
|
||||||
Get.find<AuthenticationClientBase>(tag: BindingTag.isolateTag),
|
Get.find<AuthenticationClientBase>(tag: BindingTag.isolateTag),
|
||||||
@@ -67,14 +67,7 @@ class NetworkIsolateBindings extends Bindings {
|
|||||||
if (BuildUtils.isDebugMode) {
|
if (BuildUtils.isDebugMode) {
|
||||||
dio.interceptors.add(LogInterceptor(requestBody: true));
|
dio.interceptors.add(LogInterceptor(requestBody: true));
|
||||||
}
|
}
|
||||||
if (SentryManager.instance.isSentryAvailable) {
|
SentryDioHelper.addIfAvailable(dio);
|
||||||
// Guard against duplicate Sentry interceptor registration
|
|
||||||
final alreadyHasSentry = dio.interceptors
|
|
||||||
.any((i) => i.runtimeType.toString().contains('Sentry'));
|
|
||||||
if (!alreadyHasSentry) {
|
|
||||||
dio.addSentry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bindingApi() {
|
void _bindingApi() {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:core/utils/build_utils.dart';
|
|||||||
import 'package:core/utils/config/env_loader.dart';
|
import 'package:core/utils/config/env_loader.dart';
|
||||||
import 'package:core/utils/platform_info.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
||||||
import 'package:tmail_ui_user/main.dart';
|
import 'package:tmail_ui_user/main.dart';
|
||||||
import 'package:tmail_ui_user/main/bindings/main_bindings.dart';
|
import 'package:tmail_ui_user/main/bindings/main_bindings.dart';
|
||||||
@@ -22,11 +23,11 @@ Future<void> runTmailPreload() async {
|
|||||||
await Future.wait([
|
await Future.wait([
|
||||||
MainBindings().dependencies(),
|
MainBindings().dependencies(),
|
||||||
HiveCacheConfig.instance.setUp(),
|
HiveCacheConfig.instance.setUp(),
|
||||||
Executor().warmUp(log: BuildUtils.isDebugMode),
|
|
||||||
EnvLoader.loadEnvFile(),
|
EnvLoader.loadEnvFile(),
|
||||||
if (PlatformInfo.isWeb) AssetPreloader.preloadHtmlEditorAssets(),
|
if (PlatformInfo.isWeb) AssetPreloader.preloadHtmlEditorAssets(),
|
||||||
]);
|
], eagerError: false);
|
||||||
|
|
||||||
|
await Get.find<Executor>().warmUp(log: BuildUtils.isDebugMode);
|
||||||
await CozyIntegration.integrateCozy();
|
await CozyIntegration.integrateCozy();
|
||||||
await HiveCacheConfig.instance.initializeEncryptionKey();
|
await HiveCacheConfig.instance.initializeEncryptionKey();
|
||||||
|
|
||||||
|
|||||||
@@ -1033,6 +1033,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.8.0"
|
version: "9.8.0"
|
||||||
|
sentry_dio:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sentry_dio
|
||||||
|
sha256: bee438fd790c534da77f0a6c9cd04c54c818184b8a54bbe7d916489c8aad56a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.8.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -1039,6 +1039,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.8.0"
|
version: "9.8.0"
|
||||||
|
sentry_dio:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sentry_dio
|
||||||
|
sha256: bee438fd790c534da77f0a6c9cd04c54c818184b8a54bbe7d916489c8aad56a0
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.8.0"
|
||||||
sentry_flutter:
|
sentry_flutter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user