I maintain a .NET MAUI cross-platform wrapper around RevenueCat (Kebechet/Maui.RevenueCat.InAppBilling) that exposes a single unified PurchaseErrorStatus enum to consumers. Mapping native error codes to this unified enum is harder than it should be because PurchasesErrorCode in purchases-android errors.kt and ErrorCode in purchases-ios Sources/Error Handling/ErrorCode.swift diverge in two ways for the same conceptual errors.
Cross-posted on the Android side so both teams can weigh in.
(1) Different integer codes for the same error
| Concept |
iOS code |
Android code |
CustomerInfoError |
29 |
28 |
SignatureVerificationFailed / SignatureVerificationError |
37 |
36 |
A wrapper that casts the native Int/NSInteger to a managed enum gets silently mis-mapped (e.g., Android's signature-verification failure ends up as featureNotAvailableInCustomEntitlementsComputationMode because iOS uses 36 for that).
(2) Different member names for the same error
These have aligned integer codes but different names, so even strict name-based mapping needs per-platform tables:
| Concept |
iOS name |
Android name |
Code |
| Logout while anonymous |
logOutAnonymousUserError |
LogOutWithAnonymousUserError |
22 |
| Operation in progress |
operationAlreadyInProgressForProductError |
OperationAlreadyInProgressError |
15 |
| Empty subscriber attrs |
emptySubscriberAttributes |
EmptySubscriberAttributesError |
25 |
| Signature verification failed |
signatureVerificationFailed |
SignatureVerificationError |
iOS 37 / Android 36 |
Asks (in order of preference)
-
Unify the integer codes between platforms. This is the most painful divergence — it silently produces wrong results in third-party wrappers that aren't aware of every per-platform exception.
-
If (1) is too breaking, at minimum unify the member names so by-name mapping is mechanical. Today wrappers need a hand-maintained per-platform translation table for ~4 entries that drift in spelling.
I understand either change is breaking — but a major version bump with explicit migration notes is far better than indefinite silent divergence for everyone writing cross-platform code on top of RevenueCat.
Happy to provide more context or open a PR with the rename if there's interest in option (2).
I maintain a .NET MAUI cross-platform wrapper around RevenueCat (Kebechet/Maui.RevenueCat.InAppBilling) that exposes a single unified
PurchaseErrorStatusenum to consumers. Mapping native error codes to this unified enum is harder than it should be becausePurchasesErrorCodein purchases-androiderrors.ktandErrorCodein purchases-iosSources/Error Handling/ErrorCode.swiftdiverge in two ways for the same conceptual errors.(1) Different integer codes for the same error
CustomerInfoErrorSignatureVerificationFailed/SignatureVerificationErrorA wrapper that casts the native
Int/NSIntegerto a managed enum gets silently mis-mapped (e.g., Android's signature-verification failure ends up asfeatureNotAvailableInCustomEntitlementsComputationModebecause iOS uses 36 for that).(2) Different member names for the same error
These have aligned integer codes but different names, so even strict name-based mapping needs per-platform tables:
logOutAnonymousUserErrorLogOutWithAnonymousUserErroroperationAlreadyInProgressForProductErrorOperationAlreadyInProgressErroremptySubscriberAttributesEmptySubscriberAttributesErrorsignatureVerificationFailedSignatureVerificationErrorAsks (in order of preference)
Unify the integer codes between platforms. This is the most painful divergence — it silently produces wrong results in third-party wrappers that aren't aware of every per-platform exception.
If (1) is too breaking, at minimum unify the member names so by-name mapping is mechanical. Today wrappers need a hand-maintained per-platform translation table for ~4 entries that drift in spelling.
I understand either change is breaking — but a major version bump with explicit migration notes is far better than indefinite silent divergence for everyone writing cross-platform code on top of RevenueCat.
Happy to provide more context or open a PR with the rename if there's interest in option (2).