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

[Mobile Payments] Log Stripe error codes within the CardReaderService #13976

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -235,17 +235,16 @@ extension StripeCardReaderService: CardReaderService {
return promise(.success(()))
}

self?.internalError(error)
let underlyingError = Self.logAndDecodeError(error)
discoveryLock.unlock()
let underlyingError = UnderlyingError(with: error)
promise(.failure(CardReaderServiceError.discovery(underlyingError: underlyingError)))
}
}
}
}

public func disconnect() -> Future<Void, Error> {
return Future() { promise in
return Future() { [weak self] promise in
// Throw an error if the SDK has not been initialized.
// This prevent a crash when logging out or switching stores before
// the SDK has been initialized.
Expand All @@ -271,12 +270,12 @@ extension StripeCardReaderService: CardReaderService {
Terminal.shared.disconnectReader { error in
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
promise(.failure(CardReaderServiceError.disconnection(underlyingError: underlyingError)))
}

if error == nil {
self.connectedReadersSubject.send([])
self?.connectedReadersSubject.send([])
promise(.success(()))
}
}
Expand Down Expand Up @@ -407,7 +406,7 @@ extension StripeCardReaderService: CardReaderService {
let cancelPaymentIntent = { [weak self] in
Terminal.shared.cancelPaymentIntent(activePaymentIntent) { (intent, error) in
if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
promise(.failure(CardReaderServiceError.paymentCancellation(underlyingError: underlyingError)))
}

Expand Down Expand Up @@ -473,7 +472,7 @@ extension StripeCardReaderService: CardReaderService {
let config = try buildConfig.build()
return promise(.success(config))
} catch {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
return promise(.failure(CardReaderServiceError.connection(underlyingError: underlyingError)))
}
case .failure(let error):
Expand Down Expand Up @@ -505,7 +504,7 @@ extension StripeCardReaderService: CardReaderService {
let config = try localMobileConfig.build()
return promise(.success(config))
} catch {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
return promise(.failure(CardReaderServiceError.connection(underlyingError: underlyingError)))
}
case .failure(let error):
Expand Down Expand Up @@ -537,7 +536,7 @@ extension StripeCardReaderService: CardReaderService {
self.discoveredStripeReadersCache.clear()

if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
// Starting with StripeTerminal 2.0, required software updates happen transparently on connection
// Any error related to that will be reported here, but we don't want to treat it as a connection error
let serviceError: CardReaderServiceError = underlyingError.isSoftwareUpdateError ?
Expand Down Expand Up @@ -577,7 +576,7 @@ extension StripeCardReaderService: CardReaderService {
self.discoveredStripeReadersCache.clear()

if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
// Starting with StripeTerminal 2.0, required software updates happen transparently on connection
// Any error related to that will be reported here, but we don't want to treat it as a connection error
let serviceError: CardReaderServiceError = underlyingError.isSoftwareUpdateError ?
Expand Down Expand Up @@ -641,7 +640,7 @@ private extension StripeCardReaderService {

Terminal.shared.createPaymentIntent(parameters) { (intent, error) in
if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
promise(.failure(CardReaderServiceError.intentCreation(underlyingError: underlyingError)))
}

Expand All @@ -661,7 +660,7 @@ private extension StripeCardReaderService {
/// to this cancellable if we want to cancel
self?.paymentCancellable = Terminal.shared.collectPaymentMethod(intent) { (intent, error) in
if let error = error {
var underlyingError = UnderlyingError(with: error)
var underlyingError = Self.logAndDecodeError(error)
/// the completion block for collectPaymentMethod will be called
/// with error Canceled when collectPaymentMethod is canceled
/// https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html#/c:objc(cs)SCPTerminal(im)collectPaymentMethod:delegate:completion:
Expand Down Expand Up @@ -695,7 +694,7 @@ private extension StripeCardReaderService {
Terminal.shared.confirmPaymentIntent(intent) { (intent, error) in
guard let self = self else { return }
if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)

guard let paymentIntent = error.paymentIntent else {
return promise(.failure(CardReaderServiceError.paymentCapture(underlyingError: underlyingError)))
Expand Down Expand Up @@ -766,8 +765,9 @@ extension StripeCardReaderService {
self?.refundCancellable = Terminal.shared.collectRefundPaymentMethod(parameters) { [weak self] collectError in
if let error = collectError {
self?.refundCancellable = nil
let underlyingError = Self.logAndDecodeError(error)
promise(.failure(CardReaderServiceError.refundPayment(
underlyingError: UnderlyingError(with: error),
underlyingError: underlyingError,
shouldRetry: true
)))
} else {
Expand Down Expand Up @@ -834,7 +834,8 @@ extension StripeCardReaderService {

refundCancellable.cancel({ error in
if let error = error {
promise(.failure(CardReaderServiceError.refundCancellation(underlyingError: UnderlyingError(with: error))))
let underlyingError = Self.logAndDecodeError(error)
promise(.failure(CardReaderServiceError.refundCancellation(underlyingError: underlyingError)))
}
promise(.success(()))
})
Expand Down Expand Up @@ -874,8 +875,9 @@ extension StripeCardReaderService: BluetoothReaderDelegate {

public func reader(_ reader: Reader, didFinishInstallingUpdate update: ReaderSoftwareUpdate?, error: Error?) {
if let error = error {
let underlyingError = Self.logAndDecodeError(error)
softwareUpdateSubject.send(.failed(
error: CardReaderServiceError.softwareUpdate(underlyingError: UnderlyingError(with: error),
error: CardReaderServiceError.softwareUpdate(underlyingError: underlyingError,
batteryLevel: reader.batteryLevel?.doubleValue))
)
if let requiredDate = update?.requiredAt,
Expand Down Expand Up @@ -966,8 +968,9 @@ extension StripeCardReaderService: LocalMobileReaderDelegate {

public func localMobileReader(_ reader: Reader, didFinishInstallingUpdate update: ReaderSoftwareUpdate?, error: Error?) {
if let error = error {
let underlyingError = Self.logAndDecodeError(error)
softwareUpdateSubject.send(.failed(
error: CardReaderServiceError.softwareUpdate(underlyingError: UnderlyingError(with: error),
error: CardReaderServiceError.softwareUpdate(underlyingError: underlyingError,
batteryLevel: reader.batteryLevel?.doubleValue))
)
if let requiredDate = update?.requiredAt,
Expand Down Expand Up @@ -1011,7 +1014,7 @@ private extension StripeCardReaderService {

func resetDiscoveredReadersSubject(error: Error? = nil) {
if let error = error {
let underlyingError = UnderlyingError(with: error)
let underlyingError = Self.logAndDecodeError(error)
discoveredReadersSubject.send(completion:
.failure(CardReaderServiceError.discovery(underlyingError: underlyingError))
)
Expand Down Expand Up @@ -1047,8 +1050,24 @@ private extension StripeCardReaderService {


private extension StripeCardReaderService {
func internalError(_ error: Error) {
// Empty for now. Will be implemented later
static func logAndDecodeError(_ error: Error) -> UnderlyingError {
switch error {
case is UnderlyingError:
// It's possible for errors to pass through this function more than once.
// In that scenario, we don't want to log them a second time, so we can just return.
if let underlyingError = error as? UnderlyingError {
return underlyingError
}
case is CardReaderServiceError:
DDLogError("💳 Card Reader Service Error: \(error)")
case is CardReaderConfigError:
DDLogError("💳 Card Reader Config Error: \(error)")
default:
let nsError = error as NSError
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unused

Suggested change
let nsError = error as NSError

let errorCode = ErrorCode(_nsError: error as NSError)
DDLogError("💳 Stripe Error Code: \(errorCode.code)")
}
return UnderlyingError(with: error)
}
}

Expand Down
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
20.5
-----
- [*] Blaze: Schedule a reminder local notification asking to continue abandoned campaign creation flow. [https://github.com/woocommerce/woocommerce-ios/pull/13950]
- [internal] Mobile Payments: Log errors from Stripe Terminal [https://github.com/woocommerce/woocommerce-ios/pull/13976]


20.4
Expand Down