Skip to content

fix(auth): stop reporting Block Store calls Play services doesn't support - #1670

Merged
bmc08gt merged 3 commits into
code/cashfrom
fix/blockstore-unsupported-api
Oct 5, 2026
Merged

bmc08gt merged 3 commits into
code/cashfrom
fix/blockstore-unsupported-api

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Bugsnag error 6abc0c6b991833fd09b525ad is an UnsupportedApiCallException for blockstore_retrieve_bytes_with_options v3. It comes from devices whose Play services is too old for retrieveBytes(RetrieveBytesRequest): 10 events from 3 users so far, on older vivo and realme phones running Android 11 and 12.

PlayBlockStoreBytes already catches the failure and returns null, which the class documents as the intended fallback. The noise comes from trace(error = ...), which forwards any error to Bugsnag.notify. Launch reads Block Store more than once, so each launch filed 2–3 warnings.

Read, write and delete now go through traceFailure, which logs UnsupportedApiCallException as a breadcrumb and keeps reporting everything else. Return values are unchanged.

After the first UnsupportedApiCallException from a read, later reads in the same process return null without calling Play services. There's no reliable check up front: checkApiAvailability passes because the Block Store API itself exists, and the error reports is_fully_rolled_out=false, so a Play services version gate would misjudge devices too. Writes and deletes use different features, and nothing shows them failing, so they still call through.

Every failure path now calls ensureActive() before handling the error, because runCatching was also catching coroutine cancellation. The write path is where this mattered most: a cancel during the isEndToEndEncryptionAvailable check fell back to false and went on to issue storeBytes with cloud backup off, which deletes the existing cloud copy on the next sync. ensureActive() throws only when the calling coroutine is cancelled, so a Play services task that fails with its own CancellationException is still treated as a failure.

There's no unit test: the class talks to Play services directly, and the existing tests use a fake behind BlockStoreBytes.

…port

On devices whose Play services predates blockstore_retrieve_bytes_with_options
v3, retrieveBytes fails with UnsupportedApiCallException. PlayBlockStoreBytes
already swallows it and returns null, but trace(error = ...) forwards it to
Bugsnag, so each launch filed 2-3 warnings (error 6abc0c6b991833fd09b525ad:
10 events, 3 users, older vivo and realme phones on Android 11/12).

Log that case as a breadcrumb instead. Other failures are still reported, and
return values are unchanged.
@bmc08gt bmc08gt self-assigned this Oct 5, 2026
@github-actions github-actions Bot added area: auth Login, session, access keys, identity type: fix Bug fix labels Oct 5, 2026
…upported

Launch reads Block Store 2-3 times, and on these devices every read makes a
Play services call that fails the same way. Remember the first
UnsupportedApiCallException for the process and return null after that.

There is no reliable up-front check: checkApiAvailability passes because the
Block Store API exists, and the error reports is_fully_rolled_out=false, so a
Play services version gate would also misjudge devices. Writes and deletes use
different features and keep calling through.
runCatching also caught CancellationException, so a cancelled read, write or
delete was traced as a Block Store failure and returned a fallback value
instead of cancelling.

In write, a cancel during the isEndToEndEncryptionAvailable check fell back to
false and went on to storeBytes with cloud backup off. That call starts in
Play services before its await sees the cancellation, and an unset backup flag
deletes previously backed-up data on the next sync.

Each failure path now calls ensureActive() first. It throws only when the
calling coroutine is cancelled, so a Play services task that fails with its own
CancellationException is still handled as a failure.
@bmc08gt
bmc08gt merged commit 77c6bb1 into code/cash Oct 5, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth Login, session, access keys, identity type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant