Enhance Feed Provider error handling. Fixes #2672
This commit is contained in:
parent
38f56f66b4
commit
25a9731996
|
@ -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(()))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(()))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue