Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make CoreSDKError Equatable #303

Merged
merged 9 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@

# PayPal iOS SDK Release Notes

## unreleased
* CorePayments
* Make `CoreSDKError` conform to Equatable
* Rename `NetworkingClientError` to `NetworkingError`
* Make `NetworkingError` enum and static constants public
* CardPayments
* Make `CardError` enum and static constants public
* PayPalPayments
* Make `PayPalError` enum and static constants public

## 2.0.0-beta1 (2024-11-20)
* Breaking Changes
* PayPalNativePayments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class PayPalWebViewModel: ObservableObject {
let payPalRequest = PayPalWebCheckoutRequest(orderID: orderID, fundingSource: funding)
payPalWebCheckoutClient.start(request: payPalRequest) { result, error in
if let error {
if PayPalError.isCheckoutCanceled(error) {
if error == PayPalError.checkoutCanceledError {
print("Canceled")
self.updateState(.idle)
} else {
Expand Down
10 changes: 5 additions & 5 deletions Demo/Demo/ViewModels/CardPaymentViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ class CardPaymentViewModel: ObservableObject {
let cardRequest = CardRequest(orderID: orderID, card: card, sca: sca)
cardClient?.approveOrder(request: cardRequest) { result, error in
if let error {
if CardError.isThreeDSecureCanceled(error) {
if error == CardError.threeDSecureCanceledError {
self.setApprovalCancelResult()
} else {
self.setApprovalFailureResult(vaultError: error)
self.setApprovalFailureResult(error: error)
}
} else if let result {
self.setApprovalSuccessResult(
Expand All @@ -136,7 +136,7 @@ class CardPaymentViewModel: ObservableObject {
}
}
} catch {
setApprovalFailureResult(vaultError: error)
setApprovalFailureResult(error: error)
print("failed in checkout with card. \(error.localizedDescription)")
}
}
Expand All @@ -149,9 +149,9 @@ class CardPaymentViewModel: ObservableObject {
}
}

func setApprovalFailureResult(vaultError: Error) {
func setApprovalFailureResult(error: Error) {
DispatchQueue.main.async {
self.state.approveResultResponse = .error(message: vaultError.localizedDescription)
self.state.approveResultResponse = .error(message: error.localizedDescription)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Demo/Demo/ViewModels/CardVaultViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class CardVaultViewModel: VaultViewModel {
)
)
} else if let vaultError {
if CardError.isThreeDSecureCanceled(vaultError) {
if let error = vaultError as? CoreSDKError, error == CardError.threeDSecureCanceledError {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: is it possible to make vaultError a CoreSDKError? to prevent needing a cast here?

Copy link
Collaborator Author

@KunJeongPark KunJeongPark Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, good call. Actually, clientID fetching can also throw an error in the vault function above, so that's why I cast it here.

print("Canceled")
self.state.updateSetupTokenResponse = .idle
} else {
Expand Down
2 changes: 1 addition & 1 deletion Demo/Demo/ViewModels/PayPalVaultViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PayPalVaultViewModel: VaultViewModel {
let vaultRequest = PayPalVaultRequest(setupTokenID: setupTokenID)
paypalClient.vault(vaultRequest) { result, error in
if let error {
if PayPalError.isVaultCanceled(error) {
if error == PayPalError.vaultCanceledError {
DispatchQueue.main.async {
print("Canceled")
self.state.paypalVaultTokenResponse = .idle
Expand Down
8 changes: 4 additions & 4 deletions PayPal.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
BEA100E726EF9EDA0036A6A5 /* NetworkingClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100E626EF9EDA0036A6A5 /* NetworkingClient.swift */; };
BEA100EC26EFA7790036A6A5 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100EB26EFA7790036A6A5 /* HTTPMethod.swift */; };
BEA100EE26EFA7990036A6A5 /* HTTPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100ED26EFA7990036A6A5 /* HTTPHeader.swift */; };
BEA100F026EFA7C20036A6A5 /* NetworkingClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100EF26EFA7C20036A6A5 /* NetworkingClientError.swift */; };
BEA100F026EFA7C20036A6A5 /* NetworkingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100EF26EFA7C20036A6A5 /* NetworkingError.swift */; };
BEA100F226EFA7DE0036A6A5 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA100F126EFA7DE0036A6A5 /* Environment.swift */; };
CB16E6D8285B7A2B00FD6F52 /* FakeConfirmPaymentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB16E6D7285B7A2B00FD6F52 /* FakeConfirmPaymentResponse.swift */; };
CB1A47F22820AFED00BD8184 /* PayPalPayLaterButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1A47F12820AFED00BD8184 /* PayPalPayLaterButton.swift */; };
Expand Down Expand Up @@ -275,7 +275,7 @@
BEA100E626EF9EDA0036A6A5 /* NetworkingClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkingClient.swift; sourceTree = "<group>"; };
BEA100EB26EFA7790036A6A5 /* HTTPMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = "<group>"; };
BEA100ED26EFA7990036A6A5 /* HTTPHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPHeader.swift; sourceTree = "<group>"; };
BEA100EF26EFA7C20036A6A5 /* NetworkingClientError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkingClientError.swift; sourceTree = "<group>"; };
BEA100EF26EFA7C20036A6A5 /* NetworkingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkingError.swift; sourceTree = "<group>"; };
BEA100F126EFA7DE0036A6A5 /* Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Environment.swift; sourceTree = "<group>"; };
BEDB7FE32788AB8E00CEA554 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
BEF3FF1627AC5DF3006B4B69 /* Coordinator_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator_Tests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -663,7 +663,7 @@
80E643822A1EBBD2008FD705 /* HTTPResponse.swift */,
80E2FDC22A8354AD0045593D /* RESTRequest.swift */,
807BF58E2A2A5D19002F32B3 /* HTTPResponseParser.swift */,
BEA100EF26EFA7C20036A6A5 /* NetworkingClientError.swift */,
BEA100EF26EFA7C20036A6A5 /* NetworkingError.swift */,
BC04836E27B2FB3600FA7B46 /* URLSessionProtocol.swift */,
BC04837327B2FC7300FA7B46 /* URLSession+URLSessionProtocol.swift */,
BEA100EA26EFA7670036A6A5 /* Enums */,
Expand Down Expand Up @@ -1165,7 +1165,7 @@
CB4BE27E2847EA7D00EA2DD1 /* WebAuthenticationSession.swift in Sources */,
80E2FDC12A83535A0045593D /* TrackingEventsAPI.swift in Sources */,
BEA100F226EFA7DE0036A6A5 /* Environment.swift in Sources */,
BEA100F026EFA7C20036A6A5 /* NetworkingClientError.swift in Sources */,
BEA100F026EFA7C20036A6A5 /* NetworkingError.swift in Sources */,
804E628629380B04004B9FEF /* AnalyticsService.swift in Sources */,
BC04837427B2FC7300FA7B46 /* URLSession+URLSessionProtocol.swift in Sources */,
80E2FDC32A8354AD0045593D /* RESTRequest.swift in Sources */,
Expand Down
16 changes: 8 additions & 8 deletions Sources/CardPayments/CardError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,51 +42,51 @@ public enum CardError {
case threeDSecureCanceledError
}

static let unknownError = CoreSDKError(
public static let unknownError = CoreSDKError(
code: Code.unknown.rawValue,
domain: domain,
errorDescription: "An unknown error has occured. Contact developer.paypal.com/support."
)

static let encodingError = CoreSDKError(
public static let encodingError = CoreSDKError(
code: Code.encodingError.rawValue,
domain: domain,
errorDescription: "An error occured encoding HTTP request body data. Contact developer.paypal.com/support."
)

static let threeDSecureError: (Error) -> CoreSDKError = { error in
public static let threeDSecureError: (Error) -> CoreSDKError = { error in
CoreSDKError(
code: Code.threeDSecureError.rawValue,
domain: domain,
errorDescription: error.localizedDescription
)
}

static let threeDSecureURLError = CoreSDKError(
public static let threeDSecureURLError = CoreSDKError(
code: Code.threeDSecureURLError.rawValue,
domain: domain,
errorDescription: "An invalid 3DS URL was returned. Contact developer.paypal.com/support."
)

static let threeDSecureCanceledError = CoreSDKError(
public static let threeDSecureCanceledError = CoreSDKError(
code: Code.threeDSecureCanceledError.rawValue,
domain: domain,
errorDescription: "3DS verification has been canceled by the user."
)

static let noVaultTokenDataError = CoreSDKError(
public static let noVaultTokenDataError = CoreSDKError(
code: Code.noVaultTokenDataError.rawValue,
domain: domain,
errorDescription: "No data was returned from update setup token service."
)

static let vaultTokenError = CoreSDKError(
public static let vaultTokenError = CoreSDKError(
code: Code.vaultTokenError.rawValue,
domain: domain,
errorDescription: "An error occurred while vaulting a card."
)

static let nilGraphQLClientError = CoreSDKError(
public static let nilGraphQLClientError = CoreSDKError(
code: Code.nilGraphQLClientError.rawValue,
domain: domain,
errorDescription: "GraphQLClient is unexpectedly nil."
Expand Down
2 changes: 1 addition & 1 deletion Sources/CorePayments/CoreSDKError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation

/// Error structure that SDK errors conform to
public struct CoreSDKError: Error, LocalizedError {
public struct CoreSDKError: Error, LocalizedError, Equatable {

/// The error code.
public let code: Int?
Expand Down
6 changes: 3 additions & 3 deletions Sources/CorePayments/Networking/HTTP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class HTTP {
do {
(data, response) = try await urlSession.performRequest(with: urlRequest)
} catch _ as URLError {
throw NetworkingClientError.urlSessionError
throw NetworkingError.urlSessionError
} catch {
throw NetworkingClientError.unknownError
throw NetworkingError.unknownError
}

guard let response = response as? HTTPURLResponse else {
throw NetworkingClientError.invalidURLResponseError
throw NetworkingError.invalidURLResponseError
}

return HTTPResponse(status: response.statusCode, body: data)
Expand Down
14 changes: 7 additions & 7 deletions Sources/CorePayments/Networking/HTTPResponseParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class HTTPResponseParser {

public func parseREST<T: Decodable>(_ httpResponse: HTTPResponse, as type: T.Type) throws -> T {
guard let data = httpResponse.body else {
throw NetworkingClientError.noResponseDataError
throw NetworkingError.noResponseDataError
}

if httpResponse.isSuccessful {
Expand All @@ -28,7 +28,7 @@ public class HTTPResponseParser {

public func parseGraphQL<T: Decodable>(_ httpResponse: HTTPResponse, as type: T.Type) throws -> T {
guard let data = httpResponse.body else {
throw NetworkingClientError.noResponseDataError
throw NetworkingError.noResponseDataError
}

if httpResponse.isSuccessful {
Expand All @@ -44,28 +44,28 @@ public class HTTPResponseParser {
do {
if isGraphQL {
guard let data = try decoder.decode(GraphQLHTTPResponse<T>.self, from: data).data else {
throw NetworkingClientError.noGraphQLDataKey
throw NetworkingError.noGraphQLDataKey
}
return data
} else {
return try decoder.decode(T.self, from: data)
}
} catch {
throw NetworkingClientError.jsonDecodingError(error.localizedDescription)
throw NetworkingError.jsonDecodingError(error.localizedDescription)
}
}

private func parseErrorResult<T: Decodable>(_ data: Data, as type: T.Type, isGraphQL: Bool = false) throws -> T {
do {
if isGraphQL {
let errorData = try decoder.decode(GraphQLErrorResponse.self, from: data)
throw NetworkingClientError.serverResponseError(errorData.error)
throw NetworkingError.serverResponseError(errorData.error)
} else {
let errorData = try decoder.decode(ErrorResponse.self, from: data)
throw NetworkingClientError.serverResponseError(errorData.readableDescription)
throw NetworkingError.serverResponseError(errorData.readableDescription)
}
} catch {
throw NetworkingClientError.jsonDecodingError(error.localizedDescription)
throw NetworkingError.jsonDecodingError(error.localizedDescription)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import Foundation

enum NetworkingClientError {
public enum NetworkingError {

// NEXT_MAJOR_VERSION: - Change to "NetworkingClientErrorDomain"
static let domain = "APIClientErrorDomain"
static let domain = "NetworkingClientErrorDomain"

enum Code: Int {
/// 0. An unknown error occured.
Expand Down Expand Up @@ -31,53 +30,53 @@ enum NetworkingClientError {
case noGraphQLDataKey
}

static let unknownError = CoreSDKError(
public static let unknownError = CoreSDKError(
code: Code.unknown.rawValue,
domain: domain,
errorDescription: "An unknown error occured. Contact developer.paypal.com/support."
)

static let urlSessionError = CoreSDKError(
public static let urlSessionError = CoreSDKError(
code: Code.urlSessionError.rawValue,
domain: domain,
errorDescription: "An error occured during network call. Contact developer.paypal.com/support."
)

static let jsonDecodingError: (String) -> CoreSDKError = { description in
public static let jsonDecodingError: (String) -> CoreSDKError = { description in
CoreSDKError(
code: Code.jsonDecodingError.rawValue,
domain: domain,
errorDescription: description
)
}

static let invalidURLResponseError = CoreSDKError(
public static let invalidURLResponseError = CoreSDKError(
code: Code.invalidURLResponse.rawValue,
domain: domain,
errorDescription: "An error occured due to an invalid HTTP response. Contact developer.paypal.com/support."
)

static let noResponseDataError = CoreSDKError(
public static let noResponseDataError = CoreSDKError(
code: Code.noResponseData.rawValue,
domain: domain,
errorDescription: "An error occured due to missing HTTP response data. Contact developer.paypal.com/support."
)

static let invalidURLRequestError = CoreSDKError(
public static let invalidURLRequestError = CoreSDKError(
code: Code.invalidURLRequest.rawValue,
domain: domain,
errorDescription: "An error occured constructing an HTTP request. Contact developer.paypal.com/support."
)

static let serverResponseError: (String) -> CoreSDKError = { description in
public static let serverResponseError: (String) -> CoreSDKError = { description in
CoreSDKError(
code: Code.serverResponseError.rawValue,
domain: domain,
errorDescription: description
)
}

static let noGraphQLDataKey = CoreSDKError(
public static let noGraphQLDataKey = CoreSDKError(
code: Code.noGraphQLDataKey.rawValue,
domain: domain,
errorDescription: "An error occured due to missing `data` key in GraphQL query response. Contact developer.paypal.com/support."
Expand Down
12 changes: 6 additions & 6 deletions Sources/PayPalWebPayments/PayPalError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,39 +31,39 @@ public enum PayPalError {
case vaultCanceledError
}

static let webSessionError: (Error) -> CoreSDKError = { error in
public static let webSessionError: (Error) -> CoreSDKError = { error in
CoreSDKError(
code: Code.webSessionError.rawValue,
domain: domain,
errorDescription: error.localizedDescription
)
}

static let payPalURLError = CoreSDKError(
public static let payPalURLError = CoreSDKError(
code: Code.payPalURLError.rawValue,
domain: domain,
errorDescription: "Error constructing URL for PayPal request."
)

static let malformedResultError = CoreSDKError(
public static let malformedResultError = CoreSDKError(
code: Code.malformedResultError.rawValue,
domain: domain,
errorDescription: "Result did not contain the expected data."
)

static let payPalVaultResponseError = CoreSDKError(
public static let payPalVaultResponseError = CoreSDKError(
code: Code.payPalVaultResponseError.rawValue,
domain: domain,
errorDescription: "Error parsing PayPal vault response"
)

static let checkoutCanceledError = CoreSDKError(
public static let checkoutCanceledError = CoreSDKError(
code: Code.checkoutCanceledError.rawValue,
domain: domain,
errorDescription: "PayPal checkout has been canceled by the user"
)

static let vaultCanceledError = CoreSDKError(
public static let vaultCanceledError = CoreSDKError(
code: Code.vaultCanceledError.rawValue,
domain: domain,
errorDescription: "PayPal vault has been canceled by the user"
Expand Down
Loading
Loading