-
Notifications
You must be signed in to change notification settings - Fork 109
TF-4136 Add sentry for web #4137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: improvement/tf-4136-re-standardize-the-logger
Are you sure you want to change the base?
TF-4136 Add sentry for web #4137
Conversation
189ed2d to
d7bcfe3
Compare
|
This PR has been deployed to https://linagora.github.io/tmail-flutter/4137. |
4a26f0b to
f782f91
Compare
|
Please document the expected linagora ecosystem values expected by the front. Cc @Arsnael |
cf linagora/tmail-backend#1988 , thanks |
It seems to be more TMail web configs instead cf Likely in Helm, we need to configure it as we did for the FCM env file. |
373121e to
1396d2d
Compare
296d882 to
6f63b14
Compare
Does
|
| Feature | Impact | Notes |
|---|---|---|
| Breadcrumb recording | ~0.1–0.5ms | Non-blocking |
| Error capturing | ~1–2ms async | Does not delay request |
| Upload to Sentry | Background | No impact on request |
| Debug logging | Can slow down | Only in dev/debug mode |
4. Final Conclusion
Using sentry_dio will not noticeably slow down your app. It is highly optimized, records lightweight logs, and uploads in the
background.
Why do we need
|
ebf827d to
c906563
Compare
lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
Show resolved
Hide resolved
c906563 to
ea5b1f1
Compare
|
@coderabbitai please help us review this PR |
|
@hoangdat I'll review this PR for you. Let me analyze all the changes related to the Sentry integration for web error tracking. ✅ Actions performedReview triggered.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis pull request integrates Sentry error monitoring into the Twake Mail Flutter application. Changes include adding Sentry dependencies (sentry_flutter 9.8.0, sentry_dio 9.8.0) and flutter_dotenv 5.0.2, creating Sentry configuration and initialization utilities, updating Dio from 5.0.0 to 5.2.0 across all modules, refactoring exception handling to use DioException instead of DioError, restructuring ApplicationManager as a singleton with test override support, creating an EnvLoader utility for environment configuration, refactoring the app startup flow to include SentryWidget wrapping and error handlers, integrating Sentry user tracking in dashboard controllers, and removing content-length headers from HTTP test mocks. The startup initialization flow is centralized via runAppWithMonitoring with fallback error handling. Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
=> A VERY good sign that something is utterly wrong with this work... Idea: split it in subparts, new PRs, no more than 20 file, 250 ines each, building incrementally and adding each one one layr of Sentry reporting. Cc @Crash-- |
core/lib/utils/app_logger.dart
Outdated
| if (!BuildUtils.isDebugMode) return; | ||
|
|
||
| // ignore: avoid_print | ||
| print('[TwakeMail] $formatted'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we apply the logic of print log for web?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied at #4205
| logError( | ||
| 'AuthorizationInterceptors::onError(): DIO_ERROR = $err', | ||
| exception: err.error, | ||
| stackTrace: err.stackTrace, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe only warning is enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed at #4205
|
This PR acts as a base from which related changes are split into smaller PRs for easier review and merging: |
ea5b1f1 to
47253be
Compare
|
@coderabbitai please review |
|
@dab246 I'll review the changes in this PR for you. I can see this is the base PR for the Sentry integration, and you've already started splitting it into smaller PRs like #4205 to address the review concerns about the PR size. Let me analyze all the changes related to the Sentry integration for web error tracking. ✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (6)
fcm/pubspec.yaml (1)
25-25: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
server_settings/pubspec.yaml (1)
24-24: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
forward/pubspec.yaml (1)
25-25: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
contact/pubspec.yaml (1)
28-28: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
rule_filter/pubspec.yaml (1)
25-25: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
email_recovery/pubspec.yaml (1)
25-25: LGTM - Dio upgrade supports Sentry integration.The dio upgrade to 5.2.0 is necessary for sentry_dio integration and aligns with the repo-wide dependency update.
🧹 Nitpick comments (9)
lib/features/base/base_controller.dart (1)
554-559: EnsureSentryManager.clearUser()is safe when Sentry is disabled/uninitializedHooking Sentry user clearing into
clearDataAndGoToLoginPage()is the right place. Just double‑check thatSentryManager.instance.clearUser()internally handles the “Sentry not initialized / disabled / misconfigured” case as a no‑op so that logout/data‑clear flows can never fail because of Sentry.docs/configuration/sentry_configuration.md (1)
7-29: Minor clarity tweak forSENTRY_ENABLEDexample (optional)The line
SENTRY_ENABLED=true | falseis correct but could be misread as a literal value. Consider a short note like “set totrueto enable,falseto disable” or two separate examples so it’s obvious onlytrue(lowercase) actually enables Sentry in the current implementation.core/lib/utils/sentry/sentry_initializer.dart (1)
6-32: Sentry initialization wiring looks solid;isAvailablereturn is currently redundantThe integration with
SentryFlutter.init(DSN, environment, release, tracing, breadcrumbs,beforeSend, etc.) is well structured. With the currentSentryConfig.load()behavior, any successful load already guaranteesconfig.isAvailable == true, so theboolreturn is effectively alwaystruefor now—but it’s still useful if you later changeload()to represent a “configured but disabled” state instead of throwing.core/lib/utils/sentry/sentry_config.dart (1)
47-73: Consider representing “Sentry disabled” viaisAvailableinstead of throwingThe env parsing and validation are correct, but treating
SENTRY_ENABLED != 'true'as an exception means callers must use try/catch for the normal “disabled” configuration, and anySentryConfiginstance you return will always haveisAvailable == true. A more flexible pattern would be to haveload()return a config withisAvailable = false(and maybe empty DSN) when Sentry is disabled, and let the initializer skipSentryFlutter.initin that case—while still throwing for truly invalid/missing DSN or environment. This isn’t blocking but would simplify control flow and make theisAvailableflag more meaningful.lib/features/login/data/network/interceptors/authorization_interceptors.dart (1)
85-168: Preserve stack traces when wrapping errors intoDioExceptionThe
onError(DioException err, ...)migration and retry logic look correct, but in the catch block the wrapped errors lose their stack:if (e is ServerError || e is TemporarilyUnavailable) { return super.onError( DioException(requestOptions: err.requestOptions, error: e), handler, ); } else { return super.onError(err.copyWith(error: e), handler); }Consider preserving the stack trace (and, if relevant, type/response) so callers and Sentry get full diagnostics, e.g.:
- if (e is ServerError || e is TemporarilyUnavailable) { - return super.onError( - DioException(requestOptions: err.requestOptions, error: e), - handler, - ); - } else { - return super.onError(err.copyWith(error: e), handler); - } + if (e is ServerError || e is TemporarilyUnavailable) { + return super.onError( + DioException( + requestOptions: err.requestOptions, + error: e, + stackTrace: stackTrace, + type: err.type, + response: err.response, + ), + handler, + ); + } else { + return super.onError( + err.copyWith(error: e, stackTrace: stackTrace), + handler, + ); + }This keeps network consumers and Sentry aligned with the original failure context.
lib/main/app_runner.dart (1)
1-49: Centralized monitored startup looks good; watch preloading + error handler overlapThe new
runAppWithMonitoringnicely centralizes error handling (FlutterError.onError,PlatformDispatcher.onError,runZonedGuarded) and delegates Sentry startup viaSentryManager.instance.initialize, which aligns with the updated logger.Two things to verify:
If
initializefalls back tofallBackRunner,runTmailPreload()will have already run inappRunnerand then run again insiderunTmail(). Make sure all preload steps (Hive, env, Cozy, etc.) are idempotent, or consider a fallback that just mountsTMailAppwithout re‑preloading.Given
logErrornow reports to Sentry, double‑check thatSentryManager.initializedoes not also hook the same framework error channels in a way that leads to duplicate Sentry events for a single failure.lib/main/main_entry.dart (1)
14-34: Bootstrap helpers are clear; consider makingrunTmailPreloadfully self‑contained
runTmail/runTmailPreloadnicely centralize app bootstrap (DI, Hive, executor warm‑up, env, Cozy, URL strategy). Two optional tweaks you may want to consider:
Call
WidgetsFlutterBinding.ensureInitialized()at the start ofrunTmailPreload()so it’s safe to use standalone (e.g. from tests) without relying on external callers to have initialized Flutter bindings.Gate
setPathUrlStrategy()behindPlatformInfo.isWebfor clarity, even ifurl_strategyis effectively a no‑op on non‑web platforms.core/lib/utils/app_logger.dart (1)
3-4: Error/WTF logs now go to Sentry; behavior matches platform logging rulesRouting all
logError/logWTFcalls through_internalLogintoSentryManager.instance.captureException(...)is a good fit with the earlier decision to use Sentry as a side effect of error‑level logs. The platform behavior still matches the documented rules: mobile logs only in debug via_debugPrint+BuildUtils.isDebugMode, and web can opt into production console output viawebConsoleEnabled.Two things to keep in mind:
SentryManager.captureExceptionshould be a no‑op (or otherwise safe) when Sentry is disabled or not yet initialized, so that logging from tests or early startup doesn’t throw.With
runAppWithMonitoringalso feeding framework errors intologError, verify that Sentry’s own integrations (insideSentryManager.initialize) are not additionally capturing the same events, or you may see duplicates in Sentry for a single failure.Also applies to: 50-75, 124-126
core/lib/utils/config/env_loader.dart (1)
22-35: Async callback not awaited due toVoidCallbacktype.The
onCallBackparameter is typed asVoidCallback(syncvoid Function()), but the actual callback passed at line 16-18 is async. WhenonCallBack?.call()executes on line 33, the returnedFutureis silently dropped, soloadConfigFromEnv()may not complete before execution continues.If the callback must complete before proceeding, change the signature:
static Future<void> loadFcmConfigFileToEnv({ Map<String, String>? currentMapEnvData, - VoidCallback? onCallBack, + Future<void> Function()? onCallBack, }) async { try { await dotenv.load( fileName: appFCMConfigurationPath, mergeWith: currentMapEnvData ?? {}, ); } catch (e) { logWarning('EnvLoader::loadFcmConfigFileToEnv: Exception = $e'); - onCallBack?.call(); + await onCallBack?.call(); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (9)
contact/pubspec.lockis excluded by!**/*.lockcore/pubspec.lockis excluded by!**/*.lockemail_recovery/pubspec.lockis excluded by!**/*.lockfcm/pubspec.lockis excluded by!**/*.lockforward/pubspec.lockis excluded by!**/*.lockmodel/pubspec.lockis excluded by!**/*.lockpubspec.lockis excluded by!**/*.lockrule_filter/pubspec.lockis excluded by!**/*.lockserver_settings/pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (51)
contact/pubspec.yaml(1 hunks)contact/test/contact/autocomplete_tmail_contact_method_test.dart(0 hunks)core/lib/core.dart(2 hunks)core/lib/utils/app_logger.dart(4 hunks)core/lib/utils/application_manager.dart(2 hunks)core/lib/utils/config/env_loader.dart(1 hunks)core/lib/utils/sentry/sentry_config.dart(1 hunks)core/lib/utils/sentry/sentry_initializer.dart(1 hunks)core/lib/utils/sentry/sentry_manager.dart(1 hunks)core/pubspec.yaml(2 hunks)core/test/utils/application_manager_test.dart(2 hunks)docs/configuration/sentry_configuration.md(1 hunks)email_recovery/pubspec.yaml(1 hunks)email_recovery/test/method/get_email_recovery_action_method_test.dart(0 hunks)email_recovery/test/method/set_email_recovery_action_method_test.dart(0 hunks)env.file(1 hunks)fcm/pubspec.yaml(1 hunks)fcm/test/method/firebase_registration_get_method_test.dart(0 hunks)fcm/test/method/firebase_registration_set_method_test.dart(0 hunks)forward/pubspec.yaml(1 hunks)forward/test/forward/get_forward_method_test.dart(0 hunks)forward/test/forward/set_forward_method_test.dart(0 hunks)integration_test/base/test_base.dart(2 hunks)lib/features/base/base_controller.dart(1 hunks)lib/features/login/data/network/interceptors/authorization_interceptors.dart(2 hunks)lib/features/login/data/network/oidc_http_client.dart(3 hunks)lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart(4 hunks)lib/features/manage_account/presentation/manage_account_dashboard_controller.dart(2 hunks)lib/features/upload/data/network/file_uploader.dart(1 hunks)lib/features/upload/domain/model/upload_attachment.dart(1 hunks)lib/main.dart(1 hunks)lib/main/app_runner.dart(1 hunks)lib/main/bindings/core/core_bindings.dart(0 hunks)lib/main/bindings/network/network_bindings.dart(2 hunks)lib/main/bindings/network/network_isolate_binding.dart(2 hunks)lib/main/exceptions/remote_exception_thrower.dart(2 hunks)lib/main/main_entry.dart(1 hunks)lib/main/utils/app_config.dart(0 hunks)lib/main/utils/app_utils.dart(1 hunks)lib/main/utils/toast_manager.dart(1 hunks)pubspec.yaml(2 hunks)rule_filter/pubspec.yaml(1 hunks)rule_filter/test/rule_filter/get_rule_filter_method_test.dart(0 hunks)rule_filter/test/rule_filter/set_rule_filter_method_test.dart(0 hunks)server_settings/pubspec.yaml(1 hunks)server_settings/test/server_settings/get/get_server_settings_method_test.dart(0 hunks)server_settings/test/server_settings/set/set_server_settings_method_test.dart(0 hunks)test/features/interceptor/authorization_interceptor_test.dart(4 hunks)test/features/login/data/network/oidc_http_client_test.dart(3 hunks)test/features/server_settings/data/network/server_settings_api_test.dart(0 hunks)test/features/thread/data/network/thread_api_test.dart(4 hunks)
💤 Files with no reviewable changes (14)
- email_recovery/test/method/get_email_recovery_action_method_test.dart
- fcm/test/method/firebase_registration_get_method_test.dart
- contact/test/contact/autocomplete_tmail_contact_method_test.dart
- server_settings/test/server_settings/get/get_server_settings_method_test.dart
- test/features/server_settings/data/network/server_settings_api_test.dart
- forward/test/forward/set_forward_method_test.dart
- lib/main/bindings/core/core_bindings.dart
- fcm/test/method/firebase_registration_set_method_test.dart
- forward/test/forward/get_forward_method_test.dart
- server_settings/test/server_settings/set/set_server_settings_method_test.dart
- lib/main/utils/app_config.dart
- email_recovery/test/method/set_email_recovery_action_method_test.dart
- rule_filter/test/rule_filter/get_rule_filter_method_test.dart
- rule_filter/test/rule_filter/set_rule_filter_method_test.dart
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: zatteo
Repo: linagora/tmail-flutter PR: 4196
File: scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart:34-35
Timestamp: 2025-12-09T12:47:50.713Z
Learning: The tmail-flutter codebase uses `DioError` consistently across all modules, even with Dio 5.0.0. Do not suggest replacing `DioError` with `DioException` unless it's part of a codebase-wide migration.
📚 Learning: 2025-12-09T12:47:45.861Z
Learnt from: zatteo
Repo: linagora/tmail-flutter PR: 4196
File: scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart:34-35
Timestamp: 2025-12-09T12:47:45.861Z
Learning: In the tmail-flutter repository, avoid suggesting replacing DioError with DioException unless there is a codebase-wide migration. This pattern applies to all Dart files; when reviewing, only propose a DioError-safe change (e.g., compatible error handling or conversion) unless a global migration is in place. Ensure consistency of DioError usage across modules and flag any deviations for a repo-wide decision.
Applied to files:
lib/features/login/data/network/interceptors/authorization_interceptors.dartintegration_test/base/test_base.dartlib/features/upload/data/network/file_uploader.dartlib/features/manage_account/presentation/manage_account_dashboard_controller.dartlib/features/upload/domain/model/upload_attachment.dartcore/lib/utils/sentry/sentry_manager.dartlib/main/app_runner.dartlib/main/exceptions/remote_exception_thrower.dartcore/lib/utils/sentry/sentry_config.darttest/features/thread/data/network/thread_api_test.dartcore/lib/utils/app_logger.dartlib/features/login/data/network/oidc_http_client.dartlib/main/bindings/network/network_isolate_binding.dartlib/features/base/base_controller.dartlib/main/main_entry.dartlib/main/bindings/network/network_bindings.dartcore/lib/utils/sentry/sentry_initializer.dartcore/lib/core.dartlib/main/utils/toast_manager.dartlib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dartcore/lib/utils/config/env_loader.darttest/features/interceptor/authorization_interceptor_test.darttest/features/login/data/network/oidc_http_client_test.dartlib/main.dartcore/test/utils/application_manager_test.dartcore/lib/utils/application_manager.dartlib/main/utils/app_utils.dart
📚 Learning: 2025-12-09T09:36:45.349Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4194
File: lib/features/manage_account/presentation/manage_account_dashboard_controller.dart:174-176
Timestamp: 2025-12-09T09:36:45.349Z
Learning: In Dart/Flutter projects using GetX, do not wrap getBinding<T>() calls in try/catch since they return null when not found. Only wrap Get.find<T>() calls in try/catch because they throw if a dependency is unavailable. When a binding is optional, consider checking Get.isRegistered<T>() or handling the null/exception path gracefully instead of blindly catching, and document the expectation for failure modes where a dependency may not be registered.
Applied to files:
lib/features/login/data/network/interceptors/authorization_interceptors.dartintegration_test/base/test_base.dartlib/features/upload/data/network/file_uploader.dartlib/features/manage_account/presentation/manage_account_dashboard_controller.dartlib/features/upload/domain/model/upload_attachment.dartcore/lib/utils/sentry/sentry_manager.dartlib/main/app_runner.dartlib/main/exceptions/remote_exception_thrower.dartcore/lib/utils/sentry/sentry_config.darttest/features/thread/data/network/thread_api_test.dartcore/lib/utils/app_logger.dartlib/features/login/data/network/oidc_http_client.dartlib/main/bindings/network/network_isolate_binding.dartlib/features/base/base_controller.dartlib/main/main_entry.dartlib/main/bindings/network/network_bindings.dartcore/lib/utils/sentry/sentry_initializer.dartcore/lib/core.dartlib/main/utils/toast_manager.dartlib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dartcore/lib/utils/config/env_loader.darttest/features/interceptor/authorization_interceptor_test.darttest/features/login/data/network/oidc_http_client_test.dartlib/main.dartcore/test/utils/application_manager_test.dartcore/lib/utils/application_manager.dartlib/main/utils/app_utils.dart
📚 Learning: 2025-12-09T12:47:50.713Z
Learnt from: zatteo
Repo: linagora/tmail-flutter PR: 4196
File: scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart:34-35
Timestamp: 2025-12-09T12:47:50.713Z
Learning: The tmail-flutter codebase uses `DioError` consistently across all modules, even with Dio 5.0.0. Do not suggest replacing `DioError` with `DioException` unless it's part of a codebase-wide migration.
Applied to files:
server_settings/pubspec.yamlrule_filter/pubspec.yamlfcm/pubspec.yamlemail_recovery/pubspec.yamlpubspec.yamlcore/pubspec.yamlforward/pubspec.yamlcontact/pubspec.yaml
📚 Learning: 2025-12-12T11:00:57.625Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4205
File: core/lib/utils/app_logger.dart:80-86
Timestamp: 2025-12-12T11:00:57.625Z
Learning: In the tmail-flutter codebase, logging philosophy differs by platform: web applications use the `webConsoleEnabled` parameter in `app_logger.dart` to selectively display logs in production console, while mobile applications intentionally suppress all logs in release builds (enforced by `BuildUtils.isDebugMode` check in `_debugPrint`).
Applied to files:
lib/main/app_runner.dartlib/main/main_entry.dartlib/main.dart
📚 Learning: 2025-12-12T11:00:52.914Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4205
File: core/lib/utils/app_logger.dart:80-86
Timestamp: 2025-12-12T11:00:52.914Z
Learning: In core/lib/utils/app_logger.dart, implement platform-specific logging behavior as described: web applications should respect a webConsoleEnabled flag to selectively show logs in production, while mobile platforms must suppress logs in release builds by guarding _debugPrint with BuildUtils.isDebugMode. Ensure the logging calls are conditioned on these checks and verify via builds for web and mobile (debug vs release).
Applied to files:
core/lib/utils/app_logger.dart
📚 Learning: 2025-12-12T09:03:05.962Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4204
File: lib/features/email/presentation/model/popup_menu_item_email_action.dart:34-35
Timestamp: 2025-12-12T09:03:05.962Z
Learning: In the tmail-flutter codebase, popup menu items intentionally use a consistent hoverIcon (imagePaths.icThumbsUp) across all popup item types (email actions, mailbox actions, profile settings, etc.), while actionIcon varies per action type. This is a deliberate UI/UX design choice.
Applied to files:
core/lib/utils/app_logger.dart
📚 Learning: 2025-12-12T04:54:11.121Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4191
File: lib/features/email/presentation/extensions/handle_email_action_extension.dart:37-80
Timestamp: 2025-12-12T04:54:11.121Z
Learning: In lib/features/email/presentation/extensions/handle_email_action_extension.dart, the mailboxDashBoardController.selectedEmail should only be synchronized when isMobileThreadDisabled is true. This is intentional behavior and should not be changed to update selectedEmail in non-mobile or thread-enabled contexts.
Applied to files:
lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: analyze-test (forward)
- GitHub Check: analyze-test (email_recovery)
- GitHub Check: analyze-test (fcm)
- GitHub Check: analyze-test (core)
- GitHub Check: analyze-test (contact)
- GitHub Check: analyze-test (server_settings)
- GitHub Check: analyze-test (default)
- GitHub Check: analyze-test (model)
- GitHub Check: analyze-test (rule_filter)
- GitHub Check: Build web version and deploy
🔇 Additional comments (24)
test/features/thread/data/network/thread_api_test.dart (1)
616-616: LGTM! Verify that tests pass after header cleanup.The removal of explicit
content-lengthheaders from the DioAdapter mock setup aligns with the Dio upgrade to 5.2.0 and is consistent with similar changes across other test files in this PR. Newer versions of Dio and http_mock_adapter typically handle content-length automatically, making explicit additions unnecessary.Please confirm that all tests in this file pass after removing the content-length headers to ensure the mock request matching still works correctly with Dio 5.2.0.
Also applies to: 665-665, 717-717, 755-755
integration_test/base/test_base.dart (1)
4-4: LGTM - Integration test updated for new startup flow.The changes correctly align the integration test setup with the refactored app entry point. The migration from
package:tmail_ui_user/main.darttopackage:tmail_ui_user/main/main_entry.dartand the direct call torunTmail()reflect the centralized startup architecture introduced in this PR.Also applies to: 37-37
lib/features/upload/domain/model/upload_attachment.dart (1)
65-65: The DioException migration is complete and verified.No remaining
DioErrorclass references exist in the codebase. The migration toDioExceptionhas been consistently applied across all modules, and the code at line 65 correctly usesDioExceptionwithDioExceptionType.cancel.lib/features/upload/data/network/file_uploader.dart (1)
150-155: DioException migration here looks consistent and safeCatching
DioExceptionand preserving the existingcopyWithsanitization keeps behavior aligned with the Dio 5.x API and the rest of the PR’s migration; no additional changes needed in this block.lib/main/utils/toast_manager.dart (1)
154-169: Correctly classifying empty-spam-folder failures nowPassing the
FeatureFailureinto_isEmptySpamFolderFailure(instead of the underlying exception) matches the helper’s signature and the patterns of the other branches, so empty‑spam‑folder errors will now show the intended toast.env.file (1)
12-15: Sentry env template aligns with the new config loaderThe added
SENTRY_ENABLED,SENTRY_DSN, andSENTRY_ENVIRONMENTentries match whatSentryConfig.load()expects and keep Sentry safely disabled by default until configured.lib/main/exceptions/remote_exception_thrower.dart (2)
34-60: DioException handling preserves previous semanticsSwitching to
DioExceptionwhile keeping the same status‑code mapping and fallback logic maintains the old behavior with Dio 5.x; callers will still see the same domain exceptions for each HTTP / network case.
77-97: Non-response DioException mapping remains consistentThe
_handleDioErrorWithoutResponsemapping fromDioExceptionType.*to your domain exceptions mirrors the priorDioErrorTypelogic, including theSocketException/OAuthAuthorizationErrorpassthrough, so there’s no regression in error classification here.core/lib/utils/sentry/sentry_initializer.dart (1)
34-44: beforeSend handler filtering AssertionError is straightforwardDropping
AssertionErrorevents via_beforeSendHandlerkeeps Sentry noise low; the rest of the events pass through unchanged, which is a reasonable default for a first integration step.lib/main/utils/app_utils.dart (1)
1-76: LGTM! Clean refactoring of environment loading.The removal of environment loading methods from AppUtils aligns with the new EnvLoader utility introduced in the PR. The remaining utility methods are unaffected and the refactoring improves separation of concerns.
core/lib/utils/application_manager.dart (4)
9-13: LGTM! Standard singleton pattern.The singleton implementation follows Dart best practices with a factory constructor and private internal constructor.
15-20: LGTM! Clean test injection mechanism.The test override pattern with
@visibleForTestingannotation provides a clean way to inject mock dependencies in unit tests without modifying the production code path.
28-36: LGTM! Robust error handling.The try/catch wrapper ensures getVersion never throws, returning an empty string on failure. This defensive approach prevents crashes during app startup or Sentry user agent generation.
38-71: LGTM! Comprehensive user agent handling.The implementation correctly:
- Handles platform-specific user agent retrieval (web vs mobile)
- Logs errors without crashing (returns empty string on failure)
- Provides lifecycle methods for mobile user agent initialization
- Generates proper application user agent string combining version and platform user agent
test/features/login/data/network/oidc_http_client_test.dart (1)
20-66: LGTM! Tests updated for DioException migration.The test updates correctly reflect the codebase-wide migration from DioError to DioException. Test descriptions and mock expectations are properly aligned with the implementation changes in the corresponding source file.
core/lib/core.dart (1)
63-64: LGTM! Core exports extended for Sentry and environment utilities.The new exports properly expose:
SentryManagerfor centralized error reportingEnvLoaderfor environment configuration loadingpackage_info_pluslibrary for app version accessThese additions align with the PR's Sentry integration objectives and environment loading refactoring.
Also applies to: 146-146
lib/features/login/data/network/oidc_http_client.dart (1)
8-8: LGTM! Error handling updated for DioException migration.The changes correctly migrate from DioError to DioException:
- Selective import of DioException (line 8)
- Updated catch clause (line 48)
This aligns with the codebase-wide Dio upgrade to 5.2.0 and is consistent with related test updates.
Also applies to: 48-48
lib/features/manage_account/presentation/manage_account_dashboard_controller.dart (1)
154-163: Sentry initialization order is correct.
SentryManager.instance.initialize()is called early inapp_runner.dartbefore the app is displayed, andManageAccountDashboardControlleris only instantiated when the route is navigated to. The initialization order is already properly handled by the app's startup sequence.test/features/interceptor/authorization_interceptor_test.dart (1)
44-52: Tests correctly migrated toDioExceptionThe construction of
DioExceptioninstances and the updatedthrowsA(predicate<DioException>(...))expectations are consistent with the interceptor’s newonError(DioException ...)signature and keep the token‑refresh / queued‑request scenarios well covered.Also applies to: 241-245, 250-272, 370-372
lib/main/bindings/network/network_isolate_binding.dart (1)
7-7: Isolate Dio + Sentry integration is consistent with main bindingsUsing a tagged
dioinstance, constructingAuthorizationInterceptorswith thatdio, and then conditionally addingLogInterceptor(debug only) anddio.addSentry()behindSentryManager.instance.isSentryAvailablematches the main network bindings and looks correct for isolate traffic as well.Also applies to: 55-72
lib/main.dart (1)
11-18: Clean startup flow refactoring.The delegation of monitoring initialization to
runAppWithMonitoringand app startup torunTmailimproves separation of concerns and centralizes error handling setup. This aligns well with the Sentry integration objective.core/test/utils/application_manager_test.dart (1)
20-39: Well-structured test setup with proper isolation.Good use of
debugDeviceInfoOverridefor dependency injection in tests. The comprehensive teardown ensures test isolation by resetting all global state includingPlatformInfo,debugDefaultTargetPlatformOverride, the mock method channel, andFkUserAgent.core/lib/utils/sentry/sentry_manager.dart (2)
78-87: Verify that sending user email to Sentry aligns with privacy requirements.The
setUsermethod sendsSentryUser(which can include email) to Sentry's servers. The linked issue #4136 specifies "Avoid sending sensitive data to Sentry." Confirm whether user email is acceptable for your privacy/compliance requirements, or consider using a hashed/anonymized identifier instead.
17-29: Robust initialization with graceful fallback.The initialization pattern correctly handles Sentry setup failures by catching exceptions and running the fallback runner. This ensures the app remains functional even if Sentry configuration is missing or invalid.
| flutter_svg: 2.1.0 | ||
|
|
||
| dio: 5.0.0 | ||
| dio: 5.2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
dio flutter package latest version December 2025 security vulnerabilities
💡 Result:
Summary (as of Dec 15, 2025)
- Latest dio release on pub.dev: 5.9.0 (current stable series). [1]
- Known public security issue: CRLF injection affecting dio versions < 5.0.0 (CVE-2021-31402). This was fixed by upgrading to 5.0.0+. Sources recommend using 5.0.0 or later. [2][3]
Recommended action
- Upgrade any projects using dio < 5.0.0 to the latest 5.9.0 (or the newest 5.x) and run your dependency audits/CI security scans.
- Monitor advisories (NVD/Snyk/GitHub) and the dio repo for new issues.
Sources
- dio changelog / pub.dev (package page showing latest 5.9.0). [1]
- Snyk advisory for CRLF injection in dio (fix: upgrade to >=5.0.0). [2]
- NVD / CVE-2021-31402 details. [3]
🌐 Web query:
flutter_dotenv latest version December 2025 security
💡 Result:
Latest stable flutter_dotenv version: 6.0.0 (current on pub.dev). [1][2]
Security notes and recommendations:
- The package README explicitly warns NOT to store sensitive keys (API keys/tokens) in a Flutter app because they can be extracted; flutter_dotenv does not obfuscate secrets. Use it only for non‑sensitive config (endpoints, feature flags). [2]
- Changelog/README were updated with security guidance in recent releases. [1]
- Follow general mobile best practices (keep secrets on a backend, use secure storage or platform keychains when needed). See OWASP/Flutter security guidance. [3]
Sources:
[1] flutter_dotenv changelog (pub.dev) — release notes including 6.0.0.
[2] flutter_dotenv package page (pub.dev) — Security Considerations in README.
[3] Flutter security best practices / OWASP recommendations.
🌐 Web query:
sentry_flutter latest version December 2025 security vulnerabilities
💡 Result:
Short answer
- Latest sentry_flutter (stable) on pub.dev: 9.8.0 (pub.dev listing). [1]
- No public CVE directly against the sentry_flutter Dart/Flutter SDK itself was found; recent high‑impact CVEs affect Sentry server components / other SDKs. [2][3][4]
Details and actionable points
- Package: sentry_flutter — latest stable 9.8.0 (prerelease 9.9.0-beta available). Source: pub.dev. [1]
- Notable security advisories (Dec 2025) related to Sentry ecosystem:
- CVE‑2025‑22146 — critical SAML SSO flaw in Sentry server (affects self‑hosted Sentry versions prior to the fixed release; SaaS was patched in Jan 2025). This is a server/SSO issue, not a sentry_flutter client bug. [2][5]
- CVE‑2025‑53099 — race condition / OAuth authorization handling in Sentry server (fixed in Sentry >=25.5.0). Server issue. [6]
- CVE‑2025‑65944 — sensitive HTTP headers leakage in the sentry‑javascript SDK (affects JS SDK versions) — not the Flutter SDK, but relevant if your stack uses sentry‑javascript. [7]
What this means for you
- If you only use the sentry_flutter client SDK in apps talking to Sentry SaaS (sentry.io) and your organization is on Sentry cloud, most server fixes were applied by Sentry; still ensure you run the latest sentry_flutter (9.8.0) and follow Sentry docs for secure config. [1][2]
- If you self‑host Sentry, upgrade your Sentry server to the fixed server versions (see advisories) immediately — server CVEs can allow account takeover or unauthorized access regardless of client SDK version. [2][6]
- If you also use sentry‑javascript in any web components, review CVE‑2025‑65944 guidance and update that SDK where applicable. [7]
Sources
- pub.dev — sentry_flutter package page (latest 9.8.0).
- NVD / advisories summary for CVE‑2025‑22146 (SAML SSO).
- Wiz vulnerability DB summary for CVE‑2025‑22146.
- Sentry/GitHub advisories and changelog entries (server fixes).
- CVE summary / advisory for CVE‑2025‑53099 (race condition, fixed in 25.5.0).
- Public writeups on CVE‑2025‑65944 (sentry‑javascript header leakage).
Would you like me to: (A) fetch the exact Sentry server versions that fix each CVE and links to vulnerability advisories, or (B) check whether a specific sentry_flutter release contains any security‑related fixes?
Upgrade dio to 5.9.0 and flutter_dotenv to 6.0.0 to stay current.
Current status:
sentry_flutter 9.8.0✓ is the latest stable version and has no known security vulnerabilities in the Flutter SDK.dio 5.2.0is outdated; upgrade to5.9.0(latest as of December 2025). The version is secure against known vulnerabilities (CRLF injection in dio < 5.0.0 is patched), but upgrading brings important fixes and improvements.flutter_dotenv 5.0.2is outdated; upgrade to6.0.0(latest as of December 2025). No known security vulnerabilities, but a major version update is available.
🤖 Prompt for AI Agents
In core/pubspec.yaml at line 44 update the pinned dependency versions: change
dio from 5.2.0 to 5.9.0 and also update flutter_dotenv (wherever listed in the
dependencies) from 5.0.2 to 6.0.0; then run flutter pub get to fetch new
versions and run the app/test suite to verify there are no breaking API changes
(adjust import/use if flutter_dotenv 6.x introduces API differences). Ensure
pubspec.lock is committed/updated if your workflow requires it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have many dependencies that depend on dio. So, to avoid making too many changes, and given that dio 5.2.0 is still stable for the time being, we should keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dab246, understood! That's a reasonable decision given the dependency graph complexity. Since dio 5.2.0 is secure (the CRLF injection vulnerability was fixed in 5.0.0+) and stable, keeping it to avoid cascading changes across multiple modules makes sense for now.
You can consider upgrading to a newer version of dio in a future dedicated dependency update PR when it's more convenient to address any potential breaking changes across all dependent modules.
🧠 Learnings used
Learnt from: zatteo
Repo: linagora/tmail-flutter PR: 4196
File: scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart:34-35
Timestamp: 2025-12-09T12:47:50.713Z
Learning: The tmail-flutter codebase uses `DioError` consistently across all modules, even with Dio 5.0.0. Do not suggest replacing `DioError` with `DioException` unless it's part of a codebase-wide migration.
lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart
Show resolved
Hide resolved
| flutter_svg: 2.1.0 | ||
|
|
||
| dio: 5.0.0 | ||
| dio: 5.2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
dio flutter package latest version December 2025 stable release
💡 Result:
Latest stable release: dio 5.9.0 (current on pub.dev as of Dec 15, 2025). [1]
Sources
[1] pub.dev — dio changelog and package page.
🌐 Web query:
sentry_flutter sentry_dio latest version December 2025 security vulnerabilities
💡 Result:
Summary (as of 2025-12-15)
- Latest stable package versions (pub.dev): sentry_flutter 9.8.0 and sentry_dio 9.8.0. [1][2]
- I found no public CVE or vendor advisory that reports a vulnerability in the sentry_flutter or sentry_dio SDK packages themselves as of this date. (Searches of GitHub issues, NVD/third‑party vulnerability trackers, and package pages show bug/compatibility issues but no SDK CVE entries specific to those Dart/Flutter packages.) [1][2][3]
- There are multiple recent security advisories/CVEs that affect the Sentry platform / server (self‑hosted Sentry) and other Sentry components (examples: CVE‑2024‑41656, CVE‑2024‑45605, CVE‑2025‑53099, CVE‑2025‑22146). These are platform/server issues (affect self‑hosted Sentry installs or other language SDKs in some cases) — they do not imply the sentry_flutter or sentry_dio packages are vulnerable, but they are relevant if you run a self‑hosted Sentry instance or rely on integrations. See NVD/CVE trackers for details. [4][5][6][7]
Recommendations
- If you use the pub.dev packages, upgrade to the latest stable (9.8.0) or follow the pre‑release if you need fixes in betas. [1][2]
- If you run self‑hosted Sentry, review and apply the Sentry server/security advisories (upgrade the server to patched versions mentioned in the CVE entries). [4][5][6][7]
- Monitor Sentry’s changelog / GitHub security advisories and NVD for any new SDK/server CVEs. [3][4]
Sources
- pub.dev — sentry_flutter package (latest / versions). [pub.dev/packages/sentry_flutter].
- pub.dev — sentry_dio package (latest / versions). [pub.dev/packages/sentry_dio].
- Sentry changelog / docs & GitHub issues (sdk bug reports / troubleshooting). [sentry.dev / getsentry/sentry-dart].
- NVD / CVE: CVE‑2024‑41656 (Sentry XSS).
- NVD / CVE: CVE‑2024‑45605 (authorization bug).
- NVD / CVE: CVE‑2025‑53099 (OAuth authorization code issue).
- Advisory summary (CVE‑2025‑22146) / vulnerability databases.
Would you like me to (a) watch these packages and send a follow‑up if new advisories appear, or (b) fetch the exact server versions that fix each CVE so you can map them to your deployment?
🌐 Web query:
dio 5.2.0 security vulnerabilities known issues
💡 Result:
Short answer: There are no widely reported security vulnerabilities specific to dio 5.2.0. The major public issue (CRLF injection, CVE‑2021‑31402 / GHSA) affected versions prior to 5.0.0 and was fixed in 5.0.0 — later 5.x releases (including 5.2.0) contain that fix and routine bug/security fixes. [1][2][3]
Recommendation: keep dio updated to the latest 5.x (or newer) and review the package changelog/release notes for any behavioral changes that could affect your app. [2]
Sources:
- Snyk advisory / CRLF injection (affects <5.0.0). [1]
- dio changelog / release notes showing 5.2.0 entries. [2]
- PT Security / CVE-2021-31402 details. [3]
Upgrade dio from 5.2.0 to 5.9.0.
The sentry_flutter and sentry_dio packages at 9.8.0 are already at the latest stable versions with no known security vulnerabilities. However, dio 5.2.0 is outdated; the latest stable version is 5.9.0 as of December 2025. None of the specified packages have reported security vulnerabilities.
🤖 Prompt for AI Agents
In pubspec.yaml around line 118, the dependency pin for dio is outdated (5.2.0);
update it to the latest stable 5.9.0. Edit pubspec.yaml to change the dio
version from 5.2.0 to 5.9.0, run flutter pub get (or dart pub get) to refresh
lockfile, and verify no breaking changes affect code by running the test suite
and fixing any API adjustments introduced between 5.2.0 and 5.9.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have many dependencies that depend on dio. So, to avoid making too many changes, and given that dio 5.2.0 is still stable for the time being, we should keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dab246, understood! That's a reasonable approach to manage dependency update scope, especially when multiple packages share the same dependency. Since dio 5.2.0 has no known security vulnerabilities and remains stable, keeping it for now makes sense.
Feel free to revisit the upgrade to 5.9.0 in a future PR when you're ready to update all dio-dependent packages together.
(\__/)
(•_• )
/ > 📦 (keeping stable for now)
🧠 Learnings used
Learnt from: zatteo
Repo: linagora/tmail-flutter PR: 4196
File: scribe/lib/scribe/ai/data/datasource_impl/ai_datasource_impl.dart:34-35
Timestamp: 2025-12-09T12:47:50.713Z
Learning: The tmail-flutter codebase uses `DioError` consistently across all modules, even with Dio 5.0.0. Do not suggest replacing `DioError` with `DioException` unless it's part of a codebase-wide migration.
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4137
File: lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart:32-32
Timestamp: 2025-12-15T06:24:38.823Z
Learning: In lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart and lib/features/manage_account/presentation/manage_account_dashboard_controller.dart, SentryManager.instance.setUser() intentionally sends PII (account ID, display name, username, email) to Sentry for error tracking. The team plans to document this in the app's privacy policy for transparency and compliance.

Issue
Fixes #4136
Dependency
This PR depends on:
v5.2.0jmap-dart-client#117Description
This pull request integrates Sentry error reporting to capture, track, and analyze runtime issues across the Flutter app.
It includes detailed information for each reported event such as stack trace, breadcrumbs, contexts, and custom logs — helping developers debug production errors more efficiently.
Resolved
1. Issues Captured
Sentry successfully records exceptions triggered within the application:
2. Issue Details
Detailed event information is available, including device data, environment, and app version:
3. Stack Trace
Captured stack trace for debugging and pinpointing the root cause:
4. Breadcrumbs
Breadcrumbs show user actions and app events leading up to the error:
5. Contexts: Reported Exception
Captured context includes runtime environment, user, and device information:
6. Logs
Sentry integrates with
Sentry.loggerandcaptureMessageto record structured logs:Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.