AI Disclosure: I used Claude Opus 5 when writing this bug report. I (a human) reviewed and edited the output.
Line numbers below refer to main at commit c9bef19.
Summary
The "Sentry crash-reporting opt-out" setting added in #211 appears to not be respected after an app restart.
main() reads settings.trackErrors synchronously, immediately after constructing Settings():
// lib/main.dart:23-24
var settings = Settings();
if (settings.trackErrors && !kDebugMode) {
But Settings._internal() loads config.json asynchronously:
// lib/services/settings.dart:83-97
static final Settings _instance = Settings._internal();
factory Settings() {
return _instance;
}
Settings._internal() {
_storage.readFile("config.json").then((rawConfig) { // completes later
if (rawConfig != null) {
_settings = jsonDecode(rawConfig);
}
_change.add(null);
});
}
So when main() reads settings.trackErrors, _settings is still empty and the getter falls back to its default:
// lib/services/settings.dart:10, 45-47
bool defaultTrackErrors = true;
bool get trackErrors {
return _getBool('trackErrors', defaultTrackErrors);
}
// lib/services/settings.dart:58-64
bool _getBool(String key, bool defaultValue) {
final val = _settings[key];
if (val is bool) {
return val;
}
return defaultValue;
}
A user who turns off "Report errors automatically" therefore gets Sentry re-enabled on every subsequent launch, despite the setting being correctly displayed in the UI.
Reproduction
test/models/settings_test.dart (attached) reproduces this without a device. It writes a config.json containing {"trackErrors": false, "logWrap": true}, points path_provider at that directory, and reads settings the way main() does.
$ flutter test test/models/settings_test.dart
00:00 +0 -1: settings read immediately after construction reflect config.json [E]
Expected: false
Actual: <true>
user disabled error tracking in config.json
The second test in that file is identical except that it waits for the async load, and it passes.
settings_test.dart (uploaded as a .txt because github won't let me upload a .dart file)
AI Disclosure: I used Claude Opus 5 when writing this bug report. I (a human) reviewed and edited the output.
Line numbers below refer to
mainat commitc9bef19.Summary
The "Sentry crash-reporting opt-out" setting added in #211 appears to not be respected after an app restart.
main()readssettings.trackErrorssynchronously, immediately after constructingSettings():But
Settings._internal()loadsconfig.jsonasynchronously:So when
main()readssettings.trackErrors,_settingsis still empty and the getter falls back to its default:A user who turns off "Report errors automatically" therefore gets Sentry re-enabled on every subsequent launch, despite the setting being correctly displayed in the UI.
Reproduction
test/models/settings_test.dart(attached) reproduces this without a device. It writes aconfig.jsoncontaining{"trackErrors": false, "logWrap": true}, pointspath_providerat that directory, and reads settings the waymain()does.The second test in that file is identical except that it waits for the async load, and it passes.
settings_test.dart (uploaded as a .txt because github won't let me upload a .dart file)