RevenueCat / purchases-ios

In-app purchases and subscriptions made easy. Support for iOS, watchOS, tvOS, macOS, and visionOS.
https://www.revenuecat.com/
MIT License
2.27k stars 303 forks source link

"There was a problem with the App Store." error when accessing `userCancelled` property on purchase when user cancels transaction #1947

Closed diniska closed 1 year ago

diniska commented 1 year ago

Describe the bug There is a bug on Apple TV when user presses escape button during the purchase process. Expected behaviour is that the code should receive the result with userCancelled = true. In fact when I try to read the userCancelled property the code throws an error. At the same time if user cancels the transaction using Cancel button the code returns error as expected.

For more context. There are two ways of exiting the attached screen on AppleTV. First of them is to press Cancel button and the second is by pressing Esc. The second way doesn't work as expected. Simulator Screen Shot - Apple TV 4K (at 1080p) (2nd generation) - 2022-09-28 at 11 30 52

Here is the code to reproduce the error:

Task(priority: .userInitiated) {
    do {
        let result = try await Purchases.shared.purchase(package: package)
        if result.userCancelled {
            print("Cancelled") // We expect to receive the call here when user presses Esc
        } else {
            //TODO:
        }
    } catch {
        print("Error") // The call is correctly received here when user pressed Cancel
    }
}
  1. Environment
    1. Platform: tvOS
    2. SDK version: 4.12.1
    3. StoreKit 2 (enabled with useStoreKit2IfEnabled) (Y/N): N
    4. OS version: 16.0
    5. Xcode version: 14.0
  2. When the exception is thrown the log displays the next:
    Purchase error Error Domain=RevenueCat.ErrorCode Code=2 "There was a problem with the App Store." UserInfo={readable_error_code=STORE_PROBLEM, source_file=RevenueCat/SKError+Extensions.swift:64, source_function=asPurchasesError, NSUnderlyingError=0x6000024e7cc0 {Error Domain=SKErrorDomain Code=0 "Произошла неизвестная ошибка" UserInfo={NSLocalizedDescription=Произошла неизвестная ошибка, NSUnderlyingError=0x6000024e7ab0 {Error Domain=ASDServerErrorDomain Code=5115 "The server encountered an error" UserInfo={NSLocalizedDescription=The server encountered an error}}}}, NSLocalizedDescription=There was a problem with the App Store.}
RCGitBot commented 1 year ago

👀 SDKONCALL-135 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!

NachoSoto commented 1 year ago

Thanks for the detailed report!

Could you try with version 4.13.0 released today? It includes a fix to make this consistent with StoreKit2: #1910. Also, it makes StoreKit 2 the default, which might improve the behavior here.

I do see that the internal error is Error Domain=ASDServerErrorDomain Code=5115 "The server encountered an error, which isn't documented, so basically Apple's own SDK failed to handle their own error. I wonder if you can still reproduce this with 4.13.0 though.

diniska commented 1 year ago

Thanks for the quick reply. I have just updated the version. The updated version in fact improves the result.userCancelled behaviour and I get report there instead of catching the error when user cancels the transaction using the Cancel button. At the same time the behaviour when user presses Esc stays and now shows the following in the console:

2022-09-28 11:55:13.307029+1000 ChemistryTV[45774:2652671] [Purchases] - ERROR: 🍎‼️ There was a problem with the App Store.
2022-09-28 11:55:13.307233+1000 ChemistryTV[45774:2652671] [Purchases] - ERROR: 💰 Product purchase for '<...>' failed with error: PurchasesError(error: There was a problem with the App Store., userInfo: ["source_function": "asPurchasesError", "NSUnderlyingError": StoreKit.StoreKitError.unknown, "readable_error_code": "STORE_PROBLEM", "NSLocalizedDescription": "There was a problem with the App Store.", "source_file": "RevenueCat/StoreKitError+Extensions.swift:43"])
(lldb) po error
Error Domain=RevenueCat.ErrorCode Code=2 "There was a problem with the App Store." UserInfo={source_function=asPurchasesError, NSUnderlyingError=0x60000141d380 {Error Domain=StoreKit.StoreKitError Code=2 "Не удается выполнить запрос"}, readable_error_code=STORE_PROBLEM, NSLocalizedDescription=There was a problem with the App Store., source_file=RevenueCat/StoreKitError+Extensions.swift:43}

Do you think, it is safe to assume that the error with code 2 means user escapes the transaction? Or should I show such errors to the user anyway as it could be due to some other reasons too? Just need a way to distinct valuable errors from these which could be safely discarded.

NachoSoto commented 1 year ago

Could you print error.userInfo[NSUnderlyingErrorKey]? Looks like now you're getting StoreKitError code 2, which looks like it's unknown, but maybe we can extract information from the underlying error and handle this case like we do for others in SK1.

diniska commented 1 year ago

Here is the error.userInfo[NSUnderlyingErrorKey]:

(lldb) po (error as NSError).userInfo[NSUnderlyingErrorKey]!
StoreKit.StoreKitError.unknown

And here is the userInfo itself:

(lldb) po (error as NSError).userInfo
▿ 5 elements
  ▿ 0 : 2 elements
    - key : "NSLocalizedDescription"
    - value : "There was a problem with the App Store."
  ▿ 1 : 2 elements
    - key : "readable_error_code"
    - value : "STORE_PROBLEM"
  ▿ 2 : 2 elements
    - key : "NSUnderlyingError"
    - value : StoreKit.StoreKitError.unknown
  ▿ 3 : 2 elements
    - key : "source_file"
    - value : "RevenueCat/StoreKitError+Extensions.swift:43"
  ▿ 4 : 2 elements
    - key : "source_function"
    - value : "asPurchasesError"
NachoSoto commented 1 year ago

How about po ((error as NSError).userInfo[NSUnderlyingErrorKey]! as! NSError).userInfo[NSUnderlyingErrorKey]?

diniska commented 1 year ago

Here it is:

(lldb) po ((error as NSError).userInfo[NSUnderlyingErrorKey]! as! NSError).userInfo[NSUnderlyingErrorKey]
nil

(lldb) po ((error as NSError).userInfo[NSUnderlyingErrorKey]! as! NSError).userInfo
0 elements

(lldb) po ((error as NSError).userInfo[NSUnderlyingErrorKey]! as! NSError)
StoreKit.StoreKitError.unknown
NachoSoto commented 1 year ago

So unfortunately StoreKit doesn't have any info for us to figure out that this is a cancellation. I suggest you file a Radar with Apple for this particular scenario.

diniska commented 1 year ago

Thanks for the help anyway!

NachoSoto commented 1 year ago

Thank you!

github-actions[bot] commented 1 year ago

This issue has been automatically locked due to no recent activity after it was closed. Please open a new issue for related reports.