mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
## Description: We've gotten several reports with error messages that aren't very helpful, like #2390. Turns out that whenever the API returned a non-successful response but without an error code, we always produced _"unknown error"_. This improves the behavior to default to showing the status code. One example that was very obvious is setting up the SDK with an invalid API key. ## Examples: ### `OfferingsManager.Error`: - Before: ``` [Purchases] - ERROR: 🍎‼️ Error fetching offerings - The operation couldn’t be completed. (RevenueCat.OfferingsManager.Error error 0.) Underlying error: The operation couldn’t be completed. (RevenueCat.NetworkError error 6.) ``` - After: ``` [Purchases] - ERROR: 🍎‼️ Error fetching offerings - The operation couldn’t be completed. (RevenueCat.OfferingsManager.Error error 0.) Underlying error: Unknown error. API request failed with status code 401 ``` ### `BackendError`: - Before: ``` [Purchases] - ERROR: 😿‼️ Unknown error. ``` - After: ``` [Purchases] - ERROR: 😿‼️ Unknown error. API request failed with status code 401 ``` ### Request debug logs: - Before: ``` [Purchases] - DEBUG: ℹ️ API request failed: GET /v1/subscribers/$RCAnonymousID:988f9b85609b4a57af255750bec1fbb2/offerings: Unknown error. ``` - After: ``` [Purchases] - DEBUG: ℹ️ API request failed: GET /v1/subscribers/$RCAnonymousID:988f9b85609b4a57af255750bec1fbb2/offerings: Unknown error. API request failed with status code 401 ``` ### `CustomerInfoManager`: - Before: ``` [Purchases] - WARN: ⚠️ Attempt to update CustomerInfo from network failed. The operation couldn’t be completed. (RevenueCat.BackendError error 0.) Underlying error: Unknown error ``` - After: ``` [Purchases] - WARN: ⚠️ Attempt to update CustomerInfo from network failed. The operation couldn’t be completed. (RevenueCat.BackendError error 0.) Underlying error: Unknown error. API request failed with status code 401 ```
75 lines
2.3 KiB
Swift
75 lines
2.3 KiB
Swift
//
|
||
// Copyright RevenueCat Inc. All Rights Reserved.
|
||
//
|
||
// Licensed under the MIT License (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// https://opensource.org/licenses/MIT
|
||
//
|
||
// BaseErrorTests.swift
|
||
//
|
||
// Created by Nacho Soto on 4/7/22.
|
||
|
||
// swiftlint:disable multiline_parameters
|
||
|
||
import Nimble
|
||
@testable import RevenueCat
|
||
import XCTest
|
||
|
||
class BaseErrorTests: TestCase {
|
||
|
||
/// Compares the result of calling `asPurchasesError` on a `PurchasesErrorConvertible`
|
||
/// against the expected `ErrorCode`.
|
||
final func verifyPurchasesError(
|
||
_ error: PurchasesErrorConvertible,
|
||
expectedCode: ErrorCode,
|
||
underlyingError: Error? = nil,
|
||
userInfoKeys: [NSError.UserInfoKey]? = nil,
|
||
localizedDescription: String? = nil,
|
||
file: FileString = #file, line: UInt = #line
|
||
) {
|
||
let nsError = error.asPurchasesError as NSError
|
||
|
||
expect(
|
||
file: file, line: line,
|
||
nsError.domain
|
||
) == RCPurchasesErrorCodeDomain
|
||
expect(
|
||
file: file, line: line,
|
||
nsError.code
|
||
) == expectedCode.rawValue
|
||
|
||
if let underlyingError = underlyingError {
|
||
expect(
|
||
file: file, line: line,
|
||
nsError.userInfo[NSUnderlyingErrorKey] as? NSError
|
||
).to(matchError(underlyingError),
|
||
description: "Invalid underlying error")
|
||
} else {
|
||
expect(
|
||
file: file, line: line,
|
||
nsError.userInfo[NSUnderlyingErrorKey]
|
||
).to(beNil(), description: "Expected no underlying error")
|
||
}
|
||
|
||
if let userInfoKeys = userInfoKeys {
|
||
expect(
|
||
file: file, line: line,
|
||
nsError.userInfo.keys
|
||
).to(contain(userInfoKeys as [String]))
|
||
}
|
||
|
||
if let localizedDescription = localizedDescription {
|
||
expect(
|
||
file: file, line: line,
|
||
// Testing description of the error directly.
|
||
// This ensures that converting `error as NSError` also produces a good description
|
||
// and not just "The operation couldn’t be completed."
|
||
error.localizedDescription
|
||
) == localizedDescription
|
||
}
|
||
}
|
||
|
||
}
|