Enhance Feed Provider error handling. Fixes #2672

This commit is contained in:
Maurice Parker 2020-12-15 21:39:19 -06:00
parent 38f56f66b4
commit 25a9731996
4 changed files with 46 additions and 15 deletions

View File

@ -502,9 +502,14 @@ private extension CloudKitAccountDelegate {
switch result {
case .success:
self.combinedRefresh(account, webFeeds) {
self.combinedRefresh(account, webFeeds) { result in
self.refreshProgress.clear()
account.metadata.lastArticleFetchEndTime = Date()
switch result {
case .success:
account.metadata.lastArticleFetchEndTime = Date()
case .failure(let error):
fail(error)
}
}
case .failure(let error):
@ -541,10 +546,16 @@ private extension CloudKitAccountDelegate {
switch result {
case .success:
self.refreshProgress.completeTask()
self.combinedRefresh(account, webFeeds) {
self.sendArticleStatus(for: account, showProgress: true) { _ in
self.combinedRefresh(account, webFeeds) { result in
switch result {
case .success:
self.sendArticleStatus(for: account, showProgress: true) { _ in
self.refreshProgress.clear()
account.metadata.lastArticleFetchEndTime = Date()
}
case .failure(let error):
self.refreshProgress.clear()
account.metadata.lastArticleFetchEndTime = Date()
fail(error)
}
}
case .failure(let error):
@ -559,11 +570,12 @@ private extension CloudKitAccountDelegate {
}
func combinedRefresh(_ account: Account, _ webFeeds: Set<WebFeed>, completion: @escaping () -> Void) {
func combinedRefresh(_ account: Account, _ webFeeds: Set<WebFeed>, completion: @escaping (Result<Void, Error>) -> Void) {
var refresherWebFeeds = Set<WebFeed>()
let group = DispatchGroup()
var feedProviderError: Error? = nil
for webFeed in webFeeds {
if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components) {
group.enter()
@ -588,6 +600,7 @@ private extension CloudKitAccountDelegate {
case .failure(let error):
os_log(.error, log: self.log, "CloudKit Feed refresh error: %@.", error.localizedDescription)
feedProviderError = error
self.refreshProgress.completeTask()
group.leave()
}
@ -603,7 +616,11 @@ private extension CloudKitAccountDelegate {
}
group.notify(queue: DispatchQueue.main) {
completion()
if let error = feedProviderError {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}

View File

@ -16,12 +16,15 @@ import RSWeb
public enum RedditFeedProviderError: LocalizedError {
case rateLimitExceeded
case accessFailure
case unknown
public var localizedDescription: String {
public var errorDescription: String? {
switch self {
case .rateLimitExceeded:
return NSLocalizedString("Reddit API rate limit has been exceeded. Please wait a short time and try again.", comment: "Rate Limit")
case .accessFailure:
return NSLocalizedString("An attempt to access your Reddit feed(s) failed. Please deactivate and reactivate the Reddit extension to fix this problem.", comment: "Token Renew")
case .unknown:
return NSLocalizedString("A Reddit Feed Provider error has occurred.", comment: "Unknown error")
}
@ -171,7 +174,7 @@ public final class RedditFeedProvider: FeedProvider, RedditFeedProviderTokenRefr
public func refresh(_ webFeed: WebFeed, completion: @escaping (Result<Set<ParsedItem>, Error>) -> Void) {
guard let urlComponents = URLComponents(string: webFeed.url) else {
completion(.failure(TwitterFeedProviderError.unknown))
completion(.failure(RedditFeedProviderError.unknown))
return
}
@ -363,8 +366,8 @@ private extension RedditFeedProvider {
case .failure(let oathError):
self.handleFailure(error: oathError) { error in
if let error = error {
completion(.failure(error))
if let _ = error {
completion(.failure(RedditFeedProviderError.accessFailure))
} else {
self.fetch(api: api, parameters: parameters, resultType: resultType, completion: completion)
}

View File

@ -17,7 +17,7 @@ public enum TwitterFeedProviderError: LocalizedError {
case screenNameNotFound
case unknown
public var localizedDescription: String {
public var errorDescription: String? {
switch self {
case .rateLimitExceeded:
return NSLocalizedString("Twitter API rate limit has been exceeded. Please wait a short time and try again.", comment: "Rate Limit")
@ -432,7 +432,12 @@ private extension TwitterFeedProvider {
}
case .failure(let error):
completion(.failure(error))
if error.errorCode == -11 {
// Eat these errors. They are old or invalid URL requests.
completion(.success([TwitterStatus]()))
} else {
completion(.failure(error))
}
}
}
}

View File

@ -55,6 +55,7 @@ final class LocalAccountDelegate: AccountDelegate {
refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count)
let group = DispatchGroup()
var feedProviderError: Error? = nil
for webFeed in webFeeds {
if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components) {
@ -68,6 +69,7 @@ final class LocalAccountDelegate: AccountDelegate {
}
case .failure(let error):
os_log(.error, log: self.log, "Feed Provider refresh error: %@.", error.localizedDescription)
feedProviderError = error
self.refreshProgress.completeTask()
group.leave()
}
@ -85,7 +87,11 @@ final class LocalAccountDelegate: AccountDelegate {
group.notify(queue: DispatchQueue.main) {
self.refreshProgress.clear()
account.metadata.lastArticleFetchEndTime = Date()
completion(.success(()))
if let error = feedProviderError {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}