Skip to content

Commit fb2e803

Browse files
Programcodeclaude
andcommitted
Finish a delivered transaction whose finish failed, on the next delivery
The server already has that version, so it is not sent again; an update repeating a version the server took is skipped as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent ca0cd55 commit fb2e803

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

‎apps/mobile/src/lib/purchases.test.ts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,21 @@ describe('delivering unfinished transactions', () => {
180180
expect(store.unfinishedList).toHaveLength(0);
181181
});
182182

183+
it('finishes on the next delivery a transaction whose finish failed, without sending it again', async () => {
184+
const bought = transaction(USER_A);
185+
store.unfinishedList.push(bought);
186+
env.respond = () => Promise.resolve(APPLIED);
187+
const finish = store.finish;
188+
store.finish = () => Promise.reject(new Error('StoreKit busy'));
189+
await deliverPending(USER_A);
190+
expect(store.unfinishedList).toHaveLength(1);
191+
192+
store.finish = finish;
193+
await deliverPending(USER_A);
194+
expect(env.posts).toHaveLength(1);
195+
expect(store.unfinishedList).toHaveLength(0);
196+
});
197+
183198
it('does not send a purchase under the account that signed in while the sheet was open', async () => {
184199
const sheet = deferred<StorePurchaseResult>();
185200
let opened = false;

‎apps/mobile/src/lib/purchases.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ async function post(transaction: StoreTransaction, userId: string): Promise<Deli
140140
*/
141141
async function deliver(transaction: StoreTransaction, userId: string): Promise<Delivery> {
142142
const version = transaction.signedTransaction;
143-
if (delivered.has(version)) return { ok: true, plan: delivered.get(version) ?? null };
144-
const result = await post(transaction, userId);
143+
// The server already has this version: only finish it, in case the last finish failed.
144+
const result: Delivery = delivered.has(version) ? { ok: true, plan: delivered.get(version) ?? null } : await post(transaction, userId);
145145
if (!result.ok) return result;
146146
delivered.set(version, result.plan);
147147
await storeKit()
@@ -273,6 +273,8 @@ export async function manageSubscriptions(): Promise<boolean> {
273273
function deliverUpdate(transaction: StoreTransaction, userId: string): Promise<void> {
274274
if (!belongsTo(transaction, userId)) return Promise.resolve();
275275
return serial(async () => {
276+
// A version the server already took this run was finished then; an update repeating it needs nothing.
277+
if (delivered.has(transaction.signedTransaction)) return;
276278
await deliver(transaction, userId);
277279
});
278280
}

0 commit comments

Comments
 (0)