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

DIA-2963 fix onError not called for timeouts #561

Merged
merged 3 commits into from
Apr 4, 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
7 changes: 7 additions & 0 deletions ConsentViewController/Classes/Consents/SPUserData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ public class SPConsent<ConsentType: Codable & Equatable & NSCopying>: NSObject,
usnat: .init(uuid: usnat?.consents?.uuid, webConsentPayload: usnat?.consents?.webConsentPayload)
)}

var isNotEmpty: Bool {
self != SPUserData() &&
gdpr?.consents != SPGDPRConsent.empty() &&
ccpa?.consents != SPCCPAConsent.empty() &&
usnat?.consents != SPUSNatConsent.empty()
}

override public var description: String {
"gdpr: \(String(describing: gdpr)), ccpa: \(String(describing: ccpa)), usnat: \(String(describing: usnat))"
}
Expand Down
2 changes: 1 addition & 1 deletion ConsentViewController/Classes/SPConsentManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ import UIKit
}

public func gracefullyDegradeOnError(_ error: SPError) {
if !userData.isEqual(SPUserData()) {
if userData.isNotEmpty {
spCoordinator.logErrorMetrics(error)
onConsentReady(userData: userData)
handleSDKDone()
Expand Down
45 changes: 44 additions & 1 deletion ConsentViewController/Classes/SPError.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
// swiftlint:disable line_length
@objcMembers public class SPError: NSError, LocalizedError {
public var spCode: String { "sp_metric_generic_sdk_error" }
public var spCode: String { "sp_metric_generic_sdk_error_\(code)" }

override public var description: String { "Something went wrong in the SDK" }
public var failureReason: String { originalError.debugDescription }
Expand Down Expand Up @@ -154,6 +154,49 @@ import Foundation
override public var description: String { "Something went wrong while loading the Rendering App. onMessageReady was not called within the specified timeout." }
}

@objcMembers public class ClientRequestTimeoutError: SPError {
let apiSufix: InvalidResponsAPICode
let timeoutValue: TimeInterval?

// swiftlint:disable:next force_unwrapping
var timeoutString: String { timeoutValue != nil ? String(timeoutValue!) : "" }

override public var spCode: String {
"sp_metric_client_side_timeout\(apiSufix.code)_\(timeoutString)"
}
override public var description: String {
"The request could not be fullfiled within the timeout (\(timeoutString)) specified by the client"
}

init(apiSufix: InvalidResponsAPICode, timeoutValue: TimeInterval?) {
self.apiSufix = apiSufix
self.timeoutValue = timeoutValue
super.init()
}

@available(*, unavailable)
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}

@objcMembers public class GenericNetworkError: SPError {
let apiSufix: InvalidResponsAPICode
let error: NSError

override public var spCode: String { "sp_metric_generic_network_error\(apiSufix.code)_\(error.code)" }
override public var description: String {
"Something went wrong when calling \(apiSufix.code)"
}

init(apiSufix: InvalidResponsAPICode, error: NSError) {
self.apiSufix = apiSufix
self.error = error
super.init()
}

@available(*, unavailable)
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}

@objcMembers public class UnableToInjectMessageIntoRenderingApp: SPError {
override public var spCode: String { "sp_metric_unable_to_stringify_msgJSON" }
override public var description: String { "The SDK could convert the message into JSON." }
Expand Down
13 changes: 13 additions & 0 deletions ConsentViewController/Classes/SourcePointClient/SimpleClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ class SimpleClient: HttpClient {
apiCode: apiCode,
statusCode: String(response.statusCode)
)))
} else if let error = error as? NSError {
switch error.code {
case NSURLErrorTimedOut:
handler(.failure(
ClientRequestTimeoutError(
apiSufix: apiCode,
timeoutValue: self?.session.configuration.timeoutIntervalForResource
)
))

default:
handler(.failure(GenericNetworkError(apiSufix: apiCode, error: error)))
}
}
} else {
handler(.success(data))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation

typealias ErrorHandler = (SPError) -> Void
typealias LoadMessagesReturnType = ([MessageToDisplay], SPUserData)
typealias MessagesAndConsentsHandler = (Result<LoadMessagesReturnType, SPError>) -> Void
typealias GDPRCustomConsentHandler = (Result<SPGDPRConsent, SPError>) -> Void
Expand Down Expand Up @@ -463,8 +464,14 @@ class SourcepointClientCoordinator: SPClientCoordinator {

self.authId = authId
resetStateIfAuthIdChanged()
metaData {
self.consentStatus {

let onError: ErrorHandler = {
self.logErrorMetrics($0)
handler(Result.failure($0))
}

metaData(onError) {
self.consentStatus(onError) {
self.state.udpateGDPRStatus()
self.state.udpateUSNatStatus()
self.messages { messagesResponse in
Expand Down Expand Up @@ -503,7 +510,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {
storage.spState = state
}

func metaData(next: @escaping () -> Void) {
func metaData(_ errorHandler: @escaping ErrorHandler, next: @escaping () -> Void) {
spClient.metaData(
accountId: accountId,
propertyId: propertyId,
Expand All @@ -512,11 +519,10 @@ class SourcepointClientCoordinator: SPClientCoordinator {
switch result {
case .success(let response):
self.handleMetaDataResponse(response)
next()

case .failure(let error):
self.logErrorMetrics(error)
case .failure(let error): errorHandler(error)
}
next()
}
}

Expand Down Expand Up @@ -570,7 +576,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {
storage.spState = state
}

func consentStatus(next: @escaping () -> Void) {
func consentStatus(_ errorHandler: ErrorHandler, next: @escaping () -> Void) {
if shouldCallConsentStatus {
spClient.consentStatus(
propertyId: propertyId,
Expand Down Expand Up @@ -654,6 +660,7 @@ class SourcepointClientCoordinator: SPClientCoordinator {
handler(Result.success(self.handleMessagesResponse(response)))

case .failure(let error):
self.logErrorMetrics(error)
handler(Result.failure(error))
}
}
Expand Down
Loading