Skip to content

fix: Prevent NPE in AccountViewModel.setAccountInfo#2175

Merged
nikclayton merged 3 commits intopachli:mainfrom
nikclayton:cleanup-account-activity
Mar 19, 2026
Merged

fix: Prevent NPE in AccountViewModel.setAccountInfo#2175
nikclayton merged 3 commits intopachli:mainfrom
nikclayton:cleanup-account-activity

Conversation

@nikclayton
Copy link
Copy Markdown
Contributor

Previous code could crash using:

private val activeAccount = accountManager.activeAccount!!

...

fun setAccountInfo(accountId: String) {
    this.accountId = accountId
    // NPE on next line
    this.isSelf = activeAccount.accountId == accountId
    reload(false)
}

Fix this by starting to refactor AccountViewModel to expose all of
this information as flows with correct dependencies between them.

Not all observables are converted to flows, only the minimum needed to
fix this problem. Future work will convert the other observables and
update the AccountViewModel design.

Concrete changes:

  • AccountActivity.loadedAccount is gone, AccountViewModel.accountData
    is created and collected. This emits a
    Result<Loadable.Loaded<Account>, GetAccountError> to handle failure
    cases.
  • Functions that need the account (like updateAccountAvatar()) now
    take the account as a parameter, instead of reading it from a nullable
    loadedAccount.
  • Similar changes for AccountViewModel.isSelf. This is now a stateflow
    allowing code to react to it changing while also using the current value
    in code that can't react.
  • Create AccountRepository and related classes to start holding code
    that interacts with accounts. Make this injectable with Hilt.

Instead of the implementation copied into that module.

Rename `Loadable.get()` to `getOrNull()` to be consistent with similarly
named methods in other packages.
Previous code could crash using:

```kotlin
private val activeAccount = accountManager.activeAccount!!

...

fun setAccountInfo(accountId: String) {
    this.accountId = accountId
    // NPE on next line
    this.isSelf = activeAccount.accountId == accountId
    reload(false)
}
```

Fix this by starting to refactor `AccountViewModel` to expose all of
this information as flows with correct dependencies between them.

Not all observables are converted to flows, only the minimum needed to
fix this problem. Future work will convert the other observables and
update the `AccountViewModel` design.

Concrete changes:

- `AccountActivity.loadedAccount` is gone, `AccountViewModel.accountData`
is created and collected. This emits a
`Result<Loadable.Loaded<Account>, GetAccountError>` to handle failure
cases.
- Functions that need the account (like `updateAccountAvatar()`) now
take the account as a parameter, instead of reading it from a nullable
`loadedAccount`.
- Similar changes for `AccountViewModel.isSelf`. This is now a stateflow
allowing code to react to it changing while also using the current value
in code that can't react.
- Create `AccountRepository` and related classes to start holding code
that interacts with accounts. Make this injectable with Hilt.
@nikclayton nikclayton merged commit 97e0bc1 into pachli:main Mar 19, 2026
26 checks passed
@nikclayton nikclayton deleted the cleanup-account-activity branch March 19, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant