Hey @Todd Hoff ,
Are you currently in sandbox or production when this issue occurs? This might be due to a sandbox quirk as the receipt isn’t being cleared on logout.
Apple’s sandbox environment is notoriously flaky - there are regular outages and sometimes purchases can get hung up in their system. Most of the time this error is due to sandbox downtime, but you can read about all the causes for this error in our guide on error handling here: https://docs.revenuecat.com/docs/errors#--store_problem
I don’t have a problem with the error. What I’d like to know is how to get the correct error code for what really happened. The referenced page only gives the higher level error STORE_PROBLEM
So this is really messing me up for what is supposed to be painless integration, and here we are 8 months later. Has this been addressed?
If I run Purchases.shared.restorePurchases(), I can see the underlying error but it is not passed on to the error in the completion block!
For instance, I am testing restore. If I just hit Cancel instead of logging into an Apple account, it throws an error (which would be expected) but the message is that an “The receipt is missing” error occurred. Internally though, apple passed the reason as "Authentication Failed".
Obviously, I should not show any warning to the customer if they just cancelled a login, but I have no way right now to tell the difference between an actual error that I want to handle and when I want to ignore such as in this case.
To work around this issue, can I check that the user has logged in to their Apple account before initialing restore?
Full error from inside the Revenue Cat SDK:
<SKReceiptRefreshRequest: 0x2817f1200>: Finished refreshing receipt with error: Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x281902c10 {Error Domain=AMSErrorDomain Code=100 "Authentication Failed" UserInfo={NSMultipleUnderlyingErrorsKey=(
"Error Domain=AMSErrorDomain Code=2 \"An unknown error occurred. Please try again.\" UserInfo={NSLocalizedDescription=An unknown error occurred. Please try again.}",
"Error Domain=AKAuthenticationError Code=-7003 \"(null)\""
), NSLocalizedDescription=Authentication Failed, NSLocalizedFailureReason=The authentication failed.}}, NSLocalizedFailureReason=An unknown error occurred, NSLocalizedDescription=Unhandled exception}
Error passed to restore purchase completion block:
error: Optional(Error Domain=RevenueCat.ErrorCode Code=9 "The receipt is missing." UserInfo={NSLocalizedDescription=The receipt is missing., readable_error_code=MISSING_RECEIPT_FILE, source_function=syncPurchases(receiptRefreshPolicy:isRestore:completion:), source_file=RevenueCat/PurchasesOrchestrator.swift:799})
Hi, Todd.
I’ve found that to get the underlying error (rather than the generic “unknown error”), I have to cast the error to an NSError, and then inspect the first member of the NSError's underlyingErrors array. Something like this:
if let error = error as NSError? {
let underlyingError = error.underlyingErrorsr0] as NSError
…
}
Hope that helps!
Given how many `ErrorCode` cases say “Check the underlying error for more details,” it would be super helpful to include a snippet like @Chad Mohler’s in the docs for error handling (https://www.revenuecat.com/docs/errors).
Even better, representing the underlying error somehow in the `errorUserInfo` dictionary would let a developer pass that straight through to an error reporting service without having to cast and evaluate the NSError.
I’m unsure who at RC to tag on this, maybe @ryan?