Skip to content

Commit

Permalink
Make SDK Errors Public (#1159)
Browse files Browse the repository at this point in the history
* Update all SDK errors to be public (fixes Better Error Handling #1152 and Make errors public #1080)
* Update all errors to conform to Equatable
  • Loading branch information
jaxdesmarais authored Dec 18, 2023
1 parent 3efe917 commit a9bbbec
Show file tree
Hide file tree
Showing 22 changed files with 117 additions and 102 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Braintree iOS SDK Release Notes

## unreleased
* Update all SDK errors to be public and [Equatable](https://developer.apple.com/documentation/swift/equatable) (fixes #1152 and #1080)
* BraintreeThreeDSecure
* Fix bug where `BTThreeDSecureClient.initializeChallenge()` callback wasn't properly invoked (fixes #1154)

Expand Down
2 changes: 1 addition & 1 deletion Demo/Application/Features/IdealViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class IdealViewController: PaymentButtonBaseViewController {

localPaymentClient.startPaymentFlow(request) { result, error in
guard let result else {
if (error as? NSError)?.code == 5 {
if error as? BTLocalPaymentError == .canceled("") {
self.progressBlock("Canceled 🎲")
} else {
self.progressBlock("Error: \(error?.localizedDescription ?? "")")
Expand Down
12 changes: 7 additions & 5 deletions Demo/Application/Features/SEPADirectDebitViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ class SEPADirectDebitViewController: PaymentButtonBaseViewController {
sepaDirectDebitRequest.merchantAccountID = "EUR-sepa-direct-debit"

sepaDirectDebitClient.tokenize(sepaDirectDebitRequest) { sepaDirectDebitNonce, error in
if let sepaDirectDebitNonce = sepaDirectDebitNonce {
if let sepaDirectDebitNonce {
self.completionBlock(sepaDirectDebitNonce)
} else if let error = error {
self.progressBlock(error.localizedDescription)
} else {
self.progressBlock("Canceled")
} else if let error {
if error as? BTSEPADirectDebitError == .webFlowCanceled {
self.progressBlock("Canceled")
} else {
self.progressBlock(error.localizedDescription)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Demo/Application/Features/ThreeDSecureViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ThreeDSecureViewController: PaymentButtonBaseViewController {
self.updateCallbackCount()

guard let threeDSecureResult else {
if (error as? NSError)?.code == 5 {
if error as? BTThreeDSecureError == .canceled {
self.progressBlock("Canceled 🎲")
} else {
self.progressBlock(error?.localizedDescription)
Expand Down
2 changes: 1 addition & 1 deletion Demo/Application/Features/VenmoViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class VenmoViewController: PaymentButtonBaseViewController {
progressBlock("Got a nonce 💎!")
completionBlock(venmoAccount)
} catch {
if (error as NSError).code == 10 {
if error as? BTVenmoError == .canceled {
progressBlock("Canceled 🔰")
} else {
progressBlock(error.localizedDescription)
Expand Down
8 changes: 4 additions & 4 deletions Sources/BraintreeAmericanExpress/BTAmericanExpressError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error details associated with American Express.
enum BTAmericanExpressError: Int, Error, CustomNSError, LocalizedError {
public enum BTAmericanExpressError: Int, Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error
case unknown
Expand All @@ -12,15 +12,15 @@ enum BTAmericanExpressError: Int, Error, CustomNSError, LocalizedError {
/// 2. Deallocated BTAmericanExpressClient
case deallocated

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTAmericanExpressErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
rawValue
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .unknown:
return "An unknown error occurred. Please contact support."
Expand Down
8 changes: 4 additions & 4 deletions Sources/BraintreeApplePay/BTApplePayError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error codes associated with Apple Pay.
enum BTApplePayError: Int, Error, CustomNSError, LocalizedError {
public enum BTApplePayError: Int, Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error
case unknown
Expand All @@ -15,15 +15,15 @@ enum BTApplePayError: Int, Error, CustomNSError, LocalizedError {
/// 3. Unable to create BTApplePayCardNonce
case failedToCreateNonce

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTApplePayErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
rawValue
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .unknown:
return ""
Expand Down
14 changes: 10 additions & 4 deletions Sources/BraintreeCard/BTCardError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

// Error codes associated with cards
enum BTCardError: Error, CustomNSError, LocalizedError {
public enum BTCardError: Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error
case unknown
Expand All @@ -18,11 +18,11 @@ enum BTCardError: Error, CustomNSError, LocalizedError {
/// 4. Failed to fetch Braintree configuration
case fetchConfigurationFailed

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTCardClientErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
switch self {
case .unknown:
return 0
Expand All @@ -37,7 +37,7 @@ enum BTCardError: Error, CustomNSError, LocalizedError {
}
}

var errorUserInfo: [String: Any] {
public var errorUserInfo: [String: Any] {
switch self {
case .unknown:
return [NSLocalizedDescriptionKey: "An unknown error occurred. Please contact support."]
Expand All @@ -51,4 +51,10 @@ enum BTCardError: Error, CustomNSError, LocalizedError {
return [NSLocalizedDescriptionKey: "Failed to fetch Braintree configuration."]
}
}

// MARK: - Equatable Conformance

public static func == (lhs: BTCardError, rhs: BTCardError) -> Bool {
lhs.errorCode == rhs.errorCode
}
}
8 changes: 4 additions & 4 deletions Sources/BraintreeCore/Analytics/BTAnalyticsServiceError.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import Foundation

/// Error codes associated with a API Client.
enum BTAnalyticsServiceError: Int, Error, CustomNSError, LocalizedError {
public enum BTAnalyticsServiceError: Int, Error, CustomNSError, LocalizedError, Equatable {

/// 0. Invalid API client
case invalidAPIClient

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTAnalyticsServiceErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
rawValue
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .invalidAPIClient:
return "API client must have client token or tokenization key"
Expand Down
8 changes: 4 additions & 4 deletions Sources/BraintreeCore/BTAPIClientError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error codes associated with a API Client.
enum BTAPIClientError: Int, Error, CustomNSError, LocalizedError {
public enum BTAPIClientError: Int, Error, CustomNSError, LocalizedError, Equatable {

/// 0. Configuration fetch failed
case configurationUnavailable
Expand All @@ -12,15 +12,15 @@ enum BTAPIClientError: Int, Error, CustomNSError, LocalizedError {
/// 2. Deallocated BTAPIClient
case deallocated

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTAPIClientErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
rawValue
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .configurationUnavailable:
return "The operation couldn’t be completed. Unable to fetch remote configuration from Braintree API at this time."
Expand Down
8 changes: 4 additions & 4 deletions Sources/BraintreeCore/BTClientTokenError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error codes associated with a client token.
enum BTClientTokenError: Error, CustomNSError, LocalizedError {
public enum BTClientTokenError: Error, CustomNSError, LocalizedError, Equatable {

/// 0. Authorization fingerprint was not present or invalid
case invalidAuthorizationFingerprint
Expand All @@ -18,11 +18,11 @@ enum BTClientTokenError: Error, CustomNSError, LocalizedError {
/// 4. Failed decoding from Base64 or UTF8
case failedDecoding(String)

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTClientTokenErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
switch self {
case .invalidAuthorizationFingerprint:
return 0
Expand All @@ -37,7 +37,7 @@ enum BTClientTokenError: Error, CustomNSError, LocalizedError {
}
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .invalidAuthorizationFingerprint:
return "Invalid client token. Please ensure your server is generating a valid Braintree ClientToken. Authorization fingerprint was not present or invalid."
Expand Down
14 changes: 10 additions & 4 deletions Sources/BraintreeCore/BTHTTPError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error codes associated with BTHTTP
enum BTHTTPError: Error, CustomNSError, LocalizedError {
public enum BTHTTPError: Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error (reserved)
case unknown
Expand Down Expand Up @@ -42,11 +42,11 @@ enum BTHTTPError: Error, CustomNSError, LocalizedError {
/// 12. Deallocated HTTPClient
case deallocated(String)

static var errorDomain: String {
public static var errorDomain: String {
BTCoreConstants.httpErrorDomain
}

var errorCode: Int {
public var errorCode: Int {
switch self {
case .unknown:
return 0
Expand Down Expand Up @@ -77,7 +77,7 @@ enum BTHTTPError: Error, CustomNSError, LocalizedError {
}
}

var errorUserInfo: [String : Any] {
public var errorUserInfo: [String: Any] {
switch self {
case .unknown:
return [NSLocalizedDescriptionKey: "An unexpected error occurred with the HTTP request."]
Expand Down Expand Up @@ -107,4 +107,10 @@ enum BTHTTPError: Error, CustomNSError, LocalizedError {
return [NSLocalizedDescriptionKey: "\(httpType) has been deallocated."]
}
}

// MARK: - Equatable Conformance

public static func == (lhs: BTHTTPError, rhs: BTHTTPError) -> Bool {
lhs.errorCode == rhs.errorCode
}
}
8 changes: 4 additions & 4 deletions Sources/BraintreeCore/BTJSONError.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

enum BTJSONError: Error, CustomNSError, LocalizedError {
public enum BTJSONError: Error, CustomNSError, LocalizedError, Equatable {

/// 0. JSONSerialization failure
case jsonSerializationFailure
Expand All @@ -11,11 +11,11 @@ enum BTJSONError: Error, CustomNSError, LocalizedError {
/// 2. Invalid key
case keyInvalid(String)

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTJSONErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
switch self {
case .jsonSerializationFailure:
return 0
Expand All @@ -26,7 +26,7 @@ enum BTJSONError: Error, CustomNSError, LocalizedError {
}
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .jsonSerializationFailure:
return "Failed to serialize JSON data in initilizer"
Expand Down
8 changes: 4 additions & 4 deletions Sources/BraintreeDataCollector/BTDataCollectorError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error details associated with Braintree Data Collector.
enum BTDataCollectorError: Int, Error, CustomNSError, LocalizedError {
public enum BTDataCollectorError: Int, Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error
case unknown
Expand All @@ -12,15 +12,15 @@ enum BTDataCollectorError: Int, Error, CustomNSError, LocalizedError {
/// 2. The device data could not be encoded.
case encodingFailure

static var errorDomain: String {
public static var errorDomain: String {
"com.braintreepayments.BTDataCollectorErrorDomain"
}

var errorCode: Int {
public var errorCode: Int {
rawValue
}

var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .unknown:
return "An unknown error occurred. Please contact support."
Expand Down
16 changes: 11 additions & 5 deletions Sources/BraintreeLocalPayment/BTLocalPaymentError.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Foundation

/// Error codes associated with Payment Flow
enum BTLocalPaymentError: Error, CustomNSError, LocalizedError {
public enum BTLocalPaymentError: Error, CustomNSError, LocalizedError, Equatable {

/// 0. Unknown error
case unknown

Expand Down Expand Up @@ -36,9 +36,9 @@ enum BTLocalPaymentError: Error, CustomNSError, LocalizedError {
/// 10. ASWebAuthentication error
case webSessionError(Error)

static var errorDomain = "com.braintreepayments.BTLocalPaymentErrorDomain"
public static var errorDomain = "com.braintreepayments.BTLocalPaymentErrorDomain"

var errorCode: Int {
public var errorCode: Int {
switch self {
case .unknown:
return 0
Expand All @@ -65,7 +65,7 @@ enum BTLocalPaymentError: Error, CustomNSError, LocalizedError {
}
}

var errorDescription: String {
public var errorDescription: String {
switch self {
case .unknown:
return ""
Expand All @@ -91,4 +91,10 @@ enum BTLocalPaymentError: Error, CustomNSError, LocalizedError {
return "ASWebAuthenticationSession failed with \(error.localizedDescription)"
}
}

// MARK: - Equatable Conformance

public static func == (lhs: BTLocalPaymentError, rhs: BTLocalPaymentError) -> Bool {
lhs.errorCode == rhs.errorCode
}
}
Loading

0 comments on commit a9bbbec

Please sign in to comment.