Fail gracefully when fetching statuses in timeline controller

This commit is contained in:
Shadowfacts 2021-04-04 14:43:51 -04:00
parent 5f5ef8fcea
commit edd89450aa
2 changed files with 22 additions and 4 deletions

View File

@ -72,7 +72,10 @@ class TimelineTableViewController: TimelineLikeTableViewController<TimelineEntry
let request = Client.getStatuses(timeline: timeline) let request = Client.getStatuses(timeline: timeline)
mastodonController?.run(request) { (response) in mastodonController?.run(request) { (response) in
guard case let .success(statuses, pagination) = response else { fatalError() } guard case let .success(statuses, pagination) = response else {
completion([])
return
}
self.newer = pagination?.newer self.newer = pagination?.newer
self.older = pagination?.older self.older = pagination?.older
@ -92,7 +95,10 @@ class TimelineTableViewController: TimelineLikeTableViewController<TimelineEntry
let request = Client.getStatuses(timeline: timeline, range: older) let request = Client.getStatuses(timeline: timeline, range: older)
mastodonController.run(request) { (response) in mastodonController.run(request) { (response) in
guard case let .success(statuses, pagination) = response else { fatalError() } guard case let .success(statuses, pagination) = response else {
completion([])
return
}
self.older = pagination?.older self.older = pagination?.older
@ -111,7 +117,10 @@ class TimelineTableViewController: TimelineLikeTableViewController<TimelineEntry
let request = Client.getStatuses(timeline: timeline, range: newer) let request = Client.getStatuses(timeline: timeline, range: newer)
mastodonController.run(request) { (response) in mastodonController.run(request) { (response) in
guard case let .success(statuses, pagination) = response else { fatalError() } guard case let .success(statuses, pagination) = response else {
completion([])
return
}
// if there are no new statuses, pagination is nil // if there are no new statuses, pagination is nil
// if we were to then overwrite self.newer, future refreshes would fail // if we were to then overwrite self.newer, future refreshes would fail

View File

@ -65,11 +65,18 @@ class TimelineLikeTableViewController<Item>: EnhancedTableViewController, Refres
func loadInitial() { func loadInitial() {
guard !loaded else { return } guard !loaded else { return }
// set loaded immediately so we don't trigger another request while the current one is running
loaded = true loaded = true
loadInitialItems() { (items) in loadInitialItems() { (items) in
guard items.count > 0 else { return }
DispatchQueue.main.async { DispatchQueue.main.async {
guard items.count > 0 else {
// set loaded back to false so the next time the VC appears, we try to load again
// todo: this should probably retry automatically
self.loaded = false
return
}
if self.sections.count < self.headerSectionsCount() { if self.sections.count < self.headerSectionsCount() {
self.sections.insert(contentsOf: Array(repeating: [], count: self.headerSectionsCount() - self.sections.count), at: 0) self.sections.insert(contentsOf: Array(repeating: [], count: self.headerSectionsCount() - self.sections.count), at: 0)
} }
@ -97,6 +104,8 @@ class TimelineLikeTableViewController<Item>: EnhancedTableViewController, Refres
return "Refresh" return "Refresh"
} }
// todo: these three should use Result<[Item], Client.Error> so we can differentiate between failed requests and there actually being no results
func loadInitialItems(completion: @escaping ([Item]) -> Void) { func loadInitialItems(completion: @escaping ([Item]) -> Void) {
fatalError("loadInitialItems(completion:) must be implemented by subclasses") fatalError("loadInitialItems(completion:) must be implemented by subclasses")
} }