-
Notifications
You must be signed in to change notification settings - Fork 350
Description
loadPerAccount has a check for whether the account exists or not at the end:
Future<PerAccountStore> loadPerAccount(int accountId) async {
assert(_accounts.containsKey(accountId));
final store = await doLoadPerAccount(accountId);
if (!_accounts.containsKey(accountId)) {
// [removeAccount] was called during [doLoadPerAccount].
store.dispose();
throw AccountNotFoundException();
}
return store;
}Hypothetically, this check can only be reached if the account is logged out while loading the PerAccountStore. However, because of a runtime error that would happen right after the inner request returns, we cannot reach the if-block here.
The error comes from a null-check at the start of PerAccountStore.fromInitialSnapshot:
final account = globalStore.getAccount(accountId)!;[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Null check operator used on a null value
#0 new PerAccountStore.fromInitialSnapshot (package:zulip/model/store.dart:285:54)
#1 UpdateMachine.load (package:zulip/model/store.dart:913:35)
<asynchronous suspension>
#2 LiveGlobalStore.doLoadPerAccount (package:zulip/model/store.dart:836:27)
<asynchronous suspension>
#3 GlobalStore.loadPerAccount (package:zulip/model/store.dart:155:15)
<asynchronous suspension>
#4 GlobalStore._reloadPerAccount (package:zulip/model/store.dart:135:19)
PerAccountStore.fromInitialSnapshot is called near the end of LiveGlobalStore.doLoadPerAccount with no asynchronous gap, meaning that the null-check will always fail ahead of AccountNotFoundException being raised if the user logs out during the asynchronous gap from the /api/register-queue request or globalStore.updateAccount:
This is a bug that the if (!_accounts.containsKey(accountId)) check was meant to catch. The error should be thrown earlier, ideally every time before the account is accessed, similar to the if (mounted) checks and BuildContext.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status