forked from jerrykrinock/CategoriesObjC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNSError+Recovery.m
85 lines (69 loc) · 2.42 KB
/
NSError+Recovery.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#import "NSError+Recovery.h"
#import "NSError+InfoAccess.h"
NSString* const SSYRecoveryAttempterUrlErrorKey = @"RecoveryAttempterUrl" ;
NSString* const SSYRecoveryAttempterIsAppDelegateErrorKey = @"RecoveryAttempterIsAppDelegate" ;
NSString* const SSYRetryDateErrorKey = @"RetryDate" ;
@implementation NSError (Recovery)
- (BOOL)isRecoverable {
return (
(NO
|| [self recoveryAttempter]
|| [[self userInfo] objectForKey:SSYRecoveryAttempterUrlErrorKey]
|| [[[self userInfo] objectForKey:SSYRecoveryAttempterIsAppDelegateErrorKey] boolValue]
)
&&
([[self localizedRecoveryOptions] count] > 0)
) ;
}
- (NSError*)deepestRecoverableError {
NSMutableArray* underlyingErrors = [[NSMutableArray alloc] init] ;
[underlyingErrors addObject:self] ;
NSError* error = self ;
while ((error = [[error userInfo] objectForKey:NSUnderlyingErrorKey])) {
[underlyingErrors addObject:error] ;
}
NSEnumerator* bottomUpErrors = [underlyingErrors reverseObjectEnumerator] ;
[underlyingErrors release] ;
NSError* answer = nil ;
for (error in bottomUpErrors) {
if ([error isRecoverable]) {
answer = error ;
break ;
}
}
return answer ;
}
- (id)openRecoveryAttempterForRecoveryOption:(NSInteger)recoveryOption
error_p:(NSError**)error_p {
if (error_p) {
*error_p = nil ;
}
id recoveryAttempter = [self recoveryAttempter] ;
if (!recoveryAttempter) {
NSURL* recoveryAttempterUrl = [[self userInfo] objectForKey:SSYRecoveryAttempterUrlErrorKey] ;
if (recoveryAttempterUrl) {
// recoveryOption NSAlertAlternateReturn is assumed to mean "Cancel".
if (recoveryOption == NSAlertAlternateReturn) {
return nil ;
}
recoveryAttempter = [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:recoveryAttempterUrl
display:YES
error:error_p] ;
}
else if (!recoveryAttempter) {
if ([[[self userInfo] objectForKey:SSYRecoveryAttempterIsAppDelegateErrorKey] boolValue]) {
recoveryAttempter = [NSApp delegate] ;
}
}
}
return recoveryAttempter ;
}
- (NSError*)errorByAddingRecoveryAttempterUrl:(NSURL*)url {
return [self errorByAddingUserInfoObject:url
forKey:SSYRecoveryAttempterUrlErrorKey] ;
}
- (NSError*)errorByAddingRecoveryAttempterIsAppDelegate {
return [self errorByAddingUserInfoObject:[NSNumber numberWithBool:YES]
forKey:SSYRecoveryAttempterIsAppDelegateErrorKey] ;
}
@end