firebase / firebase/firebase-cpp-sdk
Desktop RTDB: a transaction callback abort on a rerun completes the Future with kErrorNone
- Langage dominant
- C++
- Étoiles
- 326
- Forks
- 137
- Merge moyen
- 3 j 9 h
- PR mergées (30 j)
- 5
Description
### Environment
- Firebase C++ SDK 13.9.0 (desktop; the cited code is unchanged at the 13.11.0 tag)
### Summary
On desktop, if the `DoTransaction` callback aborts on the **first** invocation, the future completes with `kErrorWriteCanceled` (11) — see `Repo::StartTransaction`:
https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L659-L729
But if the abort happens on a **rerun** invocation (after a `datastale` response forces the transaction to run again), the abort reason is taken from a local `error` variable that was initialized to `kErrorNone`:
- `RerunTransactionQueue()` initializes `Error error = kErrorNone` at line 1067. If the rerun callback returns abort, line 1095 assigns that unchanged zero value to the function-local `abort_reason`.
- Lines 1111–1112 copy `abort_reason` and the current input into `FutureToComplete`. No later assignment changes the reason: line 1129 references the queued value, and lines 1131–1134 complete the Future with `CompleteWithResult(..., abort_reason, snapshot)`.
https://github.com/firebase/firebase-cpp-sdk/blob/3d7ce2a584d0b8daf1374bc2534c6ea71fa7fd6c/database/src/desktop/core/repo.cc#L1062-L1138
The result: the Future completes with `error() == kErrorNone` and a snapshot — indistinguishable from a successful commit — for a transaction that was **aborted and never committed**.
### Expected
A rerun-invocation abort should complete with the same abort code as a first-invocation abort (or, better, with `kErrorTransactionAbortedByUser` to match the mobile SDKs), never with `kErrorNone`.
### Impact
Consumers that branch on the future's error to decide "did my transaction commit?" will believe an aborted transaction succeeded whenever the abort happened after a `datastale` rerun — e.g. optimistic/fenced updates that abort once fresh data shows another writer won. In the FlutterFire Windows plugin this surfaces as `TransactionResult(committed: true)` for an aborted transaction.
### Related
Filed alongside a second desktop transaction-error report: `Repo::HandleTransactionResponse` collapses every non-`datastale` server error (including `permission_denied`) to `kErrorUnknownError` with an empty message. Both were found while debugging the same Windows application.
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
In database/src/desktop/core/repo.cc, read StartTransaction and RerunTransactionQueue first, tracing abort_reason, the local error, FutureToComplete, and CompleteWithResult. Reproduce or add coverage for a datastale-triggered rerun whose callback aborts; done means the Future reports a non-success abort code rather than kErrorNone and no commit is reported.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- cpp
- Domaine
- database, desktop
- Type d'issue
- Bug
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Activité
- Calme
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 72/100