From 0b6afb593d48528c7aff89c775a4e448a57ca570 Mon Sep 17 00:00:00 2001 From: Josh Holtz Date: Tue, 5 May 2026 19:24:03 -0500 Subject: [PATCH] Guard numeric web cancellation error codes --- __tests__/index.test.js | 19 +++++++++++++++++++ src/purchases.ts | 16 ++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/__tests__/index.test.js b/__tests__/index.test.js index bc7ecd9c6..09a073ce8 100644 --- a/__tests__/index.test.js +++ b/__tests__/index.test.js @@ -729,6 +729,25 @@ describe("Purchases", () => { }); }); + it("cancelled purchasePackage sets userCancelled when code is numeric", async () => { + NativeModules.RNPurchases.purchasePackage.mockRejectedValueOnce({ + code: 1, + message: "", + readableErrorCode: "USER_CANCELLED", + underlyingErrorMessage: undefined, + }); + + return expect(async () => { + await Purchases.purchasePackage("onemonth_freetrial") + }).rejects.toEqual({ + code: 1, + message: "", + readableErrorCode: "USER_CANCELLED", + underlyingErrorMessage: undefined, + userCancelled: true + }); + }); + it("successful purchase works", () => { NativeModules.RNPurchases.purchaseProduct.mockResolvedValueOnce({ purchasedProductIdentifier: "123", diff --git a/src/purchases.ts b/src/purchases.ts index 54c4e04b4..6244555cf 100644 --- a/src/purchases.ts +++ b/src/purchases.ts @@ -615,7 +615,7 @@ export default class Purchases { null ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -651,7 +651,7 @@ export default class Purchases { product.presentedOfferingContext ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -686,7 +686,7 @@ export default class Purchases { product.presentedOfferingContext ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -723,7 +723,7 @@ export default class Purchases { : { isPersonalizedPrice: googleIsPersonalizedPrice } ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -760,7 +760,7 @@ export default class Purchases { subscriptionOption.presentedOfferingContext ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -791,7 +791,7 @@ export default class Purchases { null ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -1226,7 +1226,7 @@ export default class Purchases { winBackOffer.identifier ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); } @@ -1260,7 +1260,7 @@ export default class Purchases { winBackOffer.identifier ).catch((error: PurchasesError) => { error.userCancelled = - error.code === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; + String(error.code) === PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR; throw error; }); }