Skip to content

Commit e0792f4

Browse files
Refine errors presented to the user
1 parent feebe25 commit e0792f4

File tree

3 files changed

+62
-25
lines changed

3 files changed

+62
-25
lines changed

ConfCore/Resource+Error.swift

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,53 @@
99
import Foundation
1010
import Siesta
1111

12-
public enum APIError: Error {
12+
public enum APIError: Error, CustomNSError {
1313
case http(Error)
1414
case adapter
1515
case unknown
1616

1717
public var localizedDescription: String {
1818
switch self {
19-
case .http(let error):
19+
case let .http(error as RequestError):
20+
return error.userMessage
21+
case let .http(error):
2022
return error.localizedDescription
2123
case .adapter:
2224
return "Unable to process the data returned by the server"
2325
case .unknown:
2426
return "An unknown networking error occurred"
2527
}
2628
}
29+
30+
public static var errorDomain: String {
31+
return "io.wwdc.error"
32+
}
33+
34+
public var errorCode: Int {
35+
switch self {
36+
case .http: return 0
37+
case .adapter: return 1
38+
case .unknown: return 2
39+
}
40+
}
41+
42+
/// The user-info dictionary.
43+
public var errorUserInfo: [String: Any] {
44+
var userInfo = [NSLocalizedDescriptionKey: localizedDescription]
45+
46+
switch self {
47+
case let .http(underlying as RequestError) where underlying.cause != nil && (underlying.cause! as NSError).domain == NSURLErrorDomain:
48+
let underlyingUserInfo = (underlying.cause! as NSError).userInfo.compactMapValues { $0 as? String }
49+
userInfo.merge(underlyingUserInfo, uniquingKeysWith: { $1 })
50+
userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Please try again"
51+
case let .http(underlying as RequestError) where underlying.cause != nil && underlying.cause! is DecodingError:
52+
userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Please report this error"
53+
case .adapter, .unknown, .http:
54+
()
55+
}
56+
57+
return userInfo
58+
}
2759
}
2860

2961
extension Resource {

ConfCore/Storage.swift

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,26 +84,23 @@ public final class Storage {
8484
}
8585

8686
func store(contentResult: Result<ContentsResponse, APIError>, completion: @escaping (Error?) -> Void) {
87-
if case let .failure(error) = contentResult {
88-
os_log("Error downloading contents: %{public}@",
87+
let contentsResponse: ContentsResponse
88+
do {
89+
contentsResponse = try contentResult.get()
90+
} catch {
91+
os_log("Error downloading contents:\n%{public}@",
8992
log: log,
9093
type: .error,
9194
String(describing: error))
92-
9395
completion(error)
94-
95-
return
96-
}
97-
98-
guard case let .success(sessionsResponse) = contentResult else {
9996
return
10097
}
10198

10299
performSerializedBackgroundWrite(writeBlock: { backgroundRealm in
103-
sessionsResponse.sessions.forEach { newSession in
100+
contentsResponse.sessions.forEach { newSession in
104101
// Replace any "unknown" resources with their full data
105102
newSession.related.filter({$0.type == RelatedResourceType.unknown.rawValue}).forEach { unknownResource in
106-
if let fullResource = sessionsResponse.resources.filter({$0.identifier == unknownResource.identifier}).first {
103+
if let fullResource = contentsResponse.resources.filter({$0.identifier == unknownResource.identifier}).first {
107104
newSession.related.replace(index: newSession.related.index(of: unknownResource)!, object: fullResource)
108105
}
109106
}
@@ -117,7 +114,7 @@ public final class Storage {
117114
}
118115

119116
// Merge existing instance data, preserving user-defined data
120-
sessionsResponse.instances.forEach { newInstance in
117+
contentsResponse.instances.forEach { newInstance in
121118
if let existingInstance = backgroundRealm.object(ofType: SessionInstance.self, forPrimaryKey: newInstance.identifier) {
122119
existingInstance.merge(with: newInstance, in: backgroundRealm)
123120
} else {
@@ -134,9 +131,9 @@ public final class Storage {
134131
}
135132

136133
// Save everything
137-
backgroundRealm.add(sessionsResponse.rooms, update: true)
138-
backgroundRealm.add(sessionsResponse.tracks, update: true)
139-
backgroundRealm.add(sessionsResponse.events, update: true)
134+
backgroundRealm.add(contentsResponse.rooms, update: true)
135+
backgroundRealm.add(contentsResponse.tracks, update: true)
136+
backgroundRealm.add(contentsResponse.events, update: true)
140137

141138
// add instances to rooms
142139
backgroundRealm.objects(Room.self).forEach { room in
@@ -225,7 +222,16 @@ public final class Storage {
225222
}
226223

227224
internal func store(liveVideosResult: Result<[SessionAsset], APIError>) {
228-
guard case .success(let assets) = liveVideosResult else { return }
225+
let assets: [SessionAsset]
226+
do {
227+
assets = try liveVideosResult.get()
228+
} catch {
229+
os_log("Error downloading live videos:\n%{public}@",
230+
log: log,
231+
type: .error,
232+
String(describing: error))
233+
return
234+
}
229235

230236
performSerializedBackgroundWrite(writeBlock: { [weak self] backgroundRealm in
231237
guard let self = self else { return }
@@ -251,19 +257,18 @@ public final class Storage {
251257
}
252258

253259
internal func store(featuredSectionsResult: Result<[FeaturedSection], APIError>, completion: @escaping (Error?) -> Void) {
254-
if case let .failure(error) = featuredSectionsResult {
255-
os_log("Error downloading featured sections: %{public}@",
260+
let sections: [FeaturedSection]
261+
do {
262+
sections = try featuredSectionsResult.get()
263+
} catch {
264+
os_log("Error downloading featured sections:\n%{public}@",
256265
log: log,
257266
type: .error,
258267
String(describing: error))
259-
260268
completion(error)
261-
262269
return
263270
}
264271

265-
guard case .success(let sections) = featuredSectionsResult else { return }
266-
267272
performSerializedBackgroundWrite(writeBlock: { backgroundRealm in
268273
let existingSections = backgroundRealm.objects(FeaturedSection.self)
269274
for section in existingSections {

WWDC/AppCoordinator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,15 @@ final class AppCoordinator {
316316

317317
_ = NotificationCenter.default.addObserver(forName: .SyncEngineDidSyncSessionsAndSchedule, object: nil, queue: .main) { note in
318318
if let error = note.object as? Error {
319-
NSApp.presentError(error)
319+
WWDCAlert.show(with: error)
320320
} else {
321321
self.updateListsAfterSync(migrate: true)
322322
}
323323
}
324324

325325
_ = NotificationCenter.default.addObserver(forName: .SyncEngineDidSyncFeaturedSections, object: nil, queue: .main) { note in
326326
if let error = note.object as? Error {
327-
NSApp.presentError(error)
327+
WWDCAlert.show(with: error)
328328
} else {
329329
self.updateFeaturedSectionsAfterSync()
330330
}

0 commit comments

Comments
 (0)