sync: a failed persist must not take the sign-in down with it

remember() runs in viewModelScope, where an escaping DataStore IO
exception is a crash. A flow we could not write down costs the reclaim,
not the sign-in the user is in the middle of.
This commit is contained in:
2026-09-09 11:42:02 +02:00
parent ead84c3195
commit c5e1dcfeb1
2 changed files with 9 additions and 3 deletions
@@ -114,8 +114,9 @@ class PendingLoginFlowStore @Inject constructor(
is NextcloudLoginFlow.PollResult.Expired -> forget()
// Still inside the window, or the server had a moment. Either way the
// token is still worth something; the deadline retires it.
// Still inside the window, or the server had a moment. Either way
// the token is still worth something, so it is left for the next
// open; a poll past the deadline answers Expired and clears it.
NextcloudLoginFlow.PollResult.Pending,
is NextcloudLoginFlow.PollResult.Failed,
-> Unit
@@ -269,7 +269,12 @@ class AddAccountViewModel @Inject constructor(
// what the flow's own doc asks for: the browser is a separate task, so
// dying while the user approves is ordinary, and the poll token is the
// only way back to the password the server is about to mint.
pendingFlow.remember(flow)
//
// ⚠️ Guarded: a DataStore write can throw, and this runs in
// viewModelScope, where an escaping exception takes the app down. A
// flow we failed to write down is a reclaim we will not get, not a
// reason to lose the sign-in in front of the user.
runCatching { pendingFlow.remember(flow) }
_state.update {
it.copy(
step = AddAccountStep.WaitingForBrowser(hostMismatch = flow.hostMismatch),