Skip to content

Commit

Permalink
ETagManager: added new verbose logs (#2656)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto authored Jun 16, 2023
1 parent 5aff9a8 commit 869642b
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 24 deletions.
4 changes: 4 additions & 0 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
4F2017D52A15587F0061F6EF /* OfflineStoreKitIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F2017D42A15587F0061F6EF /* OfflineStoreKitIntegrationTests.swift */; };
4F2018732A15797D0061F6EF /* TestLogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57057FF728B0048900995F21 /* TestLogHandler.swift */; };
4F3D56632A1E66A10070105A /* CustomerInfoManagerPostReceiptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F3D56622A1E66A10070105A /* CustomerInfoManagerPostReceiptTests.swift */; };
4F4FF3E12A3B731A0028018C /* ETagStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F4FF3E02A3B731A0028018C /* ETagStrings.swift */; };
4F54DF3F2A1D8C7500FD72BF /* MockStoreKit2TransactionFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F54DF3E2A1D8C7500FD72BF /* MockStoreKit2TransactionFetcher.swift */; };
4F54DF402A1D8C7500FD72BF /* MockStoreKit2TransactionFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F54DF3E2A1D8C7500FD72BF /* MockStoreKit2TransactionFetcher.swift */; };
4F54DF422A1D8D0700FD72BF /* MockTransactionPoster.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F54DF412A1D8D0700FD72BF /* MockTransactionPoster.swift */; };
Expand Down Expand Up @@ -921,6 +922,7 @@
4F0CE2BC2A215CE600561895 /* TransactionPosterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionPosterTests.swift; sourceTree = "<group>"; };
4F2017D42A15587F0061F6EF /* OfflineStoreKitIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineStoreKitIntegrationTests.swift; sourceTree = "<group>"; };
4F3D56622A1E66A10070105A /* CustomerInfoManagerPostReceiptTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomerInfoManagerPostReceiptTests.swift; sourceTree = "<group>"; };
4F4FF3E02A3B731A0028018C /* ETagStrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ETagStrings.swift; sourceTree = "<group>"; };
4F54DF3E2A1D8C7500FD72BF /* MockStoreKit2TransactionFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockStoreKit2TransactionFetcher.swift; sourceTree = "<group>"; };
4F54DF412A1D8D0700FD72BF /* MockTransactionPoster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTransactionPoster.swift; sourceTree = "<group>"; };
4F69EB082A14406E00ED6D4B /* Matchers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Matchers.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1456,6 +1458,7 @@
9A65E03A25918B0900DE00B0 /* CustomerInfoStrings.swift */,
4FF8464C2A32554300617F00 /* DiagnosticsStrings.swift */,
575642B52910116900719219 /* EligibilityStrings.swift */,
4F4FF3E02A3B731A0028018C /* ETagStrings.swift */,
9A65E0752591977200DE00B0 /* IdentityStrings.swift */,
2D00A41C2767C08300FC3DD8 /* ManageSubscriptionsStrings.swift */,
9A65E07A2591977500DE00B0 /* NetworkStrings.swift */,
Expand Down Expand Up @@ -3281,6 +3284,7 @@
B32B74FF26868AEB005647BF /* Package.swift in Sources */,
578DAA482948EEAD001700FD /* Clock.swift in Sources */,
2DDF41B324F6F387005BC22D /* InAppPurchaseBuilder.swift in Sources */,
4F4FF3E12A3B731A0028018C /* ETagStrings.swift in Sources */,
57D5414227F656D9004CC35C /* NetworkError.swift in Sources */,
B3781568285A79FC000A7B93 /* IdentityAPI.swift in Sources */,
B325543C2825C81800DA62EA /* Configuration.swift in Sources */,
Expand Down
71 changes: 71 additions & 0 deletions Sources/Logging/Strings/ETagStrings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// 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
//
// ETagStrings.swift
//
// Created by Nacho Soto on 6/15/23.

import Foundation

// swiftlint:disable identifier_name

enum ETagStrings {

case clearing_cache
case found_no_etag(URLRequest)
case could_not_find_cached_response_in_already_retried(response: String)
case storing_response(URLRequest, ETagManager.Response)
case not_storing_etag(HTTPResponse<Data?>)
case using_etag(URLRequest, String, Date?)
case not_using_etag(URLRequest,
VerificationResult,
needsSignatureVerification: Bool)

}

extension ETagStrings: LogMessage {

var description: String {
switch self {
case .clearing_cache:
return "Clearing ETagManager cache"

case let .found_no_etag(request):
return "Found no etag for request to '\(request.urlDescription)'"

case let .could_not_find_cached_response_in_already_retried(response):
return "We can't find the cached response, but call has already been retried. " +
"Returning result from backend \(response)"
case let .storing_response(request, response):
return "Storing etag '\(response.eTag)' for request to '\(request.urlDescription)' (\(response.statusCode))"

case let .not_storing_etag(response):
return "Not storing etag for: '\(response.description)'"

case let .using_etag(request, etag, validationTime):
return "Using etag '\(etag)' for request to '\(request.urlDescription)'. " +
"Validation time: \(validationTime?.description ?? "<null>")"

case let .not_using_etag(request, storedVerificationResult, needsSignatureVerification):
return "Not using etag for '\(request.urlDescription)'. " +
"Requested verification: \(needsSignatureVerification). Stored result: \(storedVerificationResult)"
}
}

var category: String { return "etags" }

}

private extension URLRequest {

var urlDescription: String {
return self.url?.absoluteString ?? ""
}

}
10 changes: 0 additions & 10 deletions Sources/Logging/Strings/NetworkStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ enum NetworkStrings {
case starting_next_request(request: String)
case starting_request(httpMethod: String, path: String)
case retrying_request(httpMethod: String, path: String)
case could_not_find_cached_response
case could_not_find_cached_response_in_already_retried(response: String)
case failing_url_resolved_to_host(url: URL, resolvedHost: String)
case blocked_network(url: URL, newHost: String?)
case api_request_redirect(from: URL, to: URL)
Expand Down Expand Up @@ -86,14 +84,6 @@ extension NetworkStrings: LogMessage {
case let .retrying_request(httpMethod, path):
return "Retrying request \(httpMethod) \(path)"

case .could_not_find_cached_response:
return "We were expecting to be able to return a cached response, but we can't find it. " +
"Retrying call with a new ETag."

case .could_not_find_cached_response_in_already_retried(let response):
return "We can't find the cached response, but call has already been retried. " +
"Returning result from backend \(response)"

case let .failing_url_resolved_to_host(url, resolvedHost):
return "Failing url '\(url)' resolved to host '\(resolvedHost)'"

Expand Down
1 change: 1 addition & 0 deletions Sources/Logging/Strings/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum Strings {
static let customerInfo = CustomerInfoStrings.self
static let diagnostics = DiagnosticsStrings.self
static let eligibility = EligibilityStrings.self
static let etag = ETagStrings.self
static let identity = IdentityStrings.self
static let network = NetworkStrings.self
static let offering = OfferingStrings.self
Expand Down
46 changes: 33 additions & 13 deletions Sources/Networking/HTTPClient/ETagManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ class ETagManager {
) -> [String: String] {
func eTag() -> (tag: String, date: String?)? {
if refreshETag { return nil }
guard let storedETagAndResponse = self.storedETagAndResponse(for: urlRequest) else { return nil }
guard let storedETagAndResponse = self.storedETagAndResponse(for: urlRequest) else {
Logger.verbose(Strings.etag.found_no_etag(urlRequest))
return nil
}

let shouldUseETag = (
!withSignatureVerification ||
Expand All @@ -55,9 +58,19 @@ class ETagManager {
)

if shouldUseETag {
Logger.verbose(Strings.etag.using_etag(urlRequest,
storedETagAndResponse.eTag,
storedETagAndResponse.validationTime))

return (tag: storedETagAndResponse.eTag,
date: storedETagAndResponse.validationTime?.millisecondsSince1970.description)
} else {
Logger.verbose(Strings.etag.not_using_etag(
urlRequest,
storedETagAndResponse.verificationResult,
needsSignatureVerification: withSignatureVerification

))
return nil
}
}
Expand Down Expand Up @@ -90,7 +103,7 @@ class ETagManager {
}
if retried {
Logger.warn(
Strings.network.could_not_find_cached_response_in_already_retried(
Strings.etag.could_not_find_cached_response_in_already_retried(
response: resultFromBackend?.description ?? ""
)
)
Expand All @@ -108,6 +121,8 @@ class ETagManager {
}

func clearCaches() {
Logger.debug(Strings.etag.clearing_cache)

self.userDefaults.write {
$0.removePersistentDomain(forName: ETagManager.suiteName)
}
Expand Down Expand Up @@ -140,23 +155,28 @@ private extension ETagManager {
func storeStatusCodeAndResponseIfNoError(for request: URLRequest,
response: HTTPResponse<Data?>,
eTag: String) {
if let data = response.body,
response.shouldStore(ignoreVerificationErrors: self.shouldIgnoreVerificationErrors) {
self.storeIfPossible(
Response(
eTag: eTag,
statusCode: response.statusCode,
data: data,
verificationResult: response.verificationResult
),
for: request
)
if let data = response.body {
if response.shouldStore(ignoreVerificationErrors: self.shouldIgnoreVerificationErrors) {
self.storeIfPossible(
Response(
eTag: eTag,
statusCode: response.statusCode,
data: data,
verificationResult: response.verificationResult
),
for: request
)
} else {
Logger.verbose(Strings.etag.not_storing_etag(response))
}
}
}

func storeIfPossible(_ response: Response, for request: URLRequest) {
if let cacheKey = self.eTagDefaultCacheKey(for: request),
let dataToStore = response.asData() {
Logger.verbose(Strings.etag.storing_response(request, response))

self.userDefaults.write {
$0.set(dataToStore, forKey: cacheKey)
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/UnitTests/Purchasing/ErrorUtilsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class ErrorUtilsTests: TestCase {
}

func testNetworkErrorsAreLogged() {
let error = ErrorUtils.networkError(message: Strings.network.could_not_find_cached_response.description)
let error = ErrorUtils.networkError(message: Strings.network.json_data_received(dataString: "test").description)

self.expectLoggedError(error, .rcError)
}
Expand Down

0 comments on commit 869642b

Please sign in to comment.