Skip to content

Commit ef18804

Browse files
committed
• Fixed recovery attempting in SSYAlert. It looks like the patching I did to please the SDK upgrades on 2015-11-23 commit 4e65af7 ignored the important case of the error containing a recovery attempter instead of a recovery URL.
1 parent e22edb3 commit ef18804

File tree

1 file changed

+89
-70
lines changed

1 file changed

+89
-70
lines changed

SSYAlert.m

+89-70
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,6 @@ + (NSInteger)tryRecoveryAttempterForError:(NSError*)error
548548
contextInfo:(NSMutableDictionary*)infoDictionary {
549549
NSUInteger result = SSYAlertRecoveryNotAttempted ;
550550

551-
NSError* deepestRecoverableError = [error deepestRecoverableError] ;
552551
id recoveryAttempter ;
553552
if ([[[error userInfo] objectForKey:SSYRecoveryAttempterIsAppDelegateErrorKey] boolValue]) {
554553
recoveryAttempter = [NSApp delegate] ;
@@ -557,7 +556,13 @@ + (NSInteger)tryRecoveryAttempterForError:(NSError*)error
557556
recoveryAttempter = [error recoveryAttempter] ;
558557
}
559558

560-
if (!recoveryAttempter) {
559+
if (recoveryAttempter) {
560+
[self attemptRecoveryFromError:error
561+
infoDictionary:infoDictionary
562+
recoveryOption:recoveryOption
563+
recoveryAttempter:recoveryAttempter] ;
564+
}
565+
else {
561566
NSURL* recoveryAttempterUrl = [[error userInfo] objectForKey:SSYRecoveryAttempterUrlErrorKey] ;
562567
if (recoveryAttempterUrl) {
563568
// recoveryOption NSAlertSecondButtonReturn is assumed to mean "Cancel".
@@ -570,73 +575,13 @@ + (NSInteger)tryRecoveryAttempterForError:(NSError*)error
570575
BOOL documentWasAlreadyOpen,
571576
NSError* documentOpeningError) {
572577
if (newDocument) {
573-
// Try the sheet method, attemptRecoveryFromError::::: first, since, in my
574-
// opinion, it gives a better user experience. If the recoveryAttempter
575-
// does not respond to that, try the window method, attemptRecoveryFromError::
576-
if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:recoveryOption:delegate:didRecoverSelector:contextInfo:)]) {
577-
NSInvocation* invocation = [error didRecoverInvocation] ;
578-
id delegate = [invocation target] ;
579-
SEL didRecoverSelector = [invocation selector] ;
580-
// I put the whole invocation into the context info, believing it to be alot cleaner.
581-
if (invocation) {
582-
// Before we invoke the didRecoverInvocation, we also put it into the
583-
// current infoDictionary in case an error occurs again and we need
584-
// to re-recover.
585-
[infoDictionary setObject:invocation
586-
forKey:SSYAlertDidRecoverInvocationKey] ;
587-
}
588-
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
589-
recoveryOption:recoveryOption
590-
delegate:delegate
591-
didRecoverSelector:didRecoverSelector
592-
contextInfo:(__bridge void *)(infoDictionary)] ;
593-
}
594-
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:)]) {
595-
/* This is an error produced by Cocoa.
596-
In particular, in macOS 10.7, it might be one like this:
597-
Error Domain = NSCocoaErrorDomain
598-
Code = 67000
599-
UserInfo = {
600-
• NSLocalizedRecoverySuggestion=Click Save Anyway to keep your changes and save the
601-
changes made by the other application as a version, or click Revert to keep the changes from the other
602-
application and save your changes as a version.
603-
• NSLocalizedFailureReason=The file has been changed by another application.
604-
• NSLocalizedDescription=This document’s file has been changed by another application.
605-
• NSLocalizedRecoveryOptions = ("Save Anyway", "Revert")
606-
}
607-
*/
608-
NSInvocation* invocation = [error didRecoverInvocation] ;
609-
id delegate = [invocation target] ;
610-
SEL didRecoverSelector = [invocation selector] ;
611-
// I put the whole invocation into the context info, believing it to be alot cleaner.
612-
if (invocation) {
613-
// Before we invoke the didRecoverInvocation, we also put it into the
614-
// current infoDictionary in case an error occurs again and we need
615-
// to re-recover.
616-
[infoDictionary setObject:invocation
617-
forKey:SSYAlertDidRecoverInvocationKey] ;
618-
}
619-
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
620-
621-
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
622-
optionIndex:recoveryOptionIndex
623-
delegate:delegate
624-
didRecoverSelector:didRecoverSelector
625-
contextInfo:(__bridge void *)(infoDictionary)] ;
626-
}
627-
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:recoveryOption:)]) {
628-
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
629-
recoveryOption:recoveryOption] ;
630-
}
631-
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:)]) {
632-
// This is an error produced by Cocoa.
633-
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
634-
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
635-
optionIndex:recoveryOptionIndex] ;
636-
}
637-
else if (recoveryAttempter != nil) {
638-
NSLog(@"Internal Error 342-5587. Given Recovery Attempter %@ does not respond to any attemptRecoveryFromError:... method", recoveryAttempter) ;
639-
}
578+
[self attemptRecoveryFromError:error
579+
infoDictionary:infoDictionary
580+
recoveryOption:recoveryOption
581+
recoveryAttempter:newDocument] ;
582+
}
583+
else if (documentOpeningError) {
584+
[self alertError:documentOpeningError] ;
640585
}
641586
}] ;
642587
}
@@ -646,6 +591,80 @@ + (NSInteger)tryRecoveryAttempterForError:(NSError*)error
646591
return result ;
647592
}
648593

594+
+ (void)attemptRecoveryFromError:(NSError*)error
595+
infoDictionary:(NSMutableDictionary*)infoDictionary
596+
recoveryOption:(NSUInteger)recoveryOption
597+
recoveryAttempter:(id)recoveryAttempter {
598+
NSError* deepestRecoverableError = [error deepestRecoverableError] ;
599+
// Try the sheet method, attemptRecoveryFromError::::: first, since, in my
600+
// opinion, it gives a better user experience. If the recoveryAttempter
601+
// does not respond to that, try the window method, attemptRecoveryFromError::
602+
if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:recoveryOption:delegate:didRecoverSelector:contextInfo:)]) {
603+
NSInvocation* invocation = [error didRecoverInvocation] ;
604+
id delegate = [invocation target] ;
605+
SEL didRecoverSelector = [invocation selector] ;
606+
// I put the whole invocation into the context info, believing it to be alot cleaner.
607+
if (invocation) {
608+
// Before we invoke the didRecoverInvocation, we also put it into the
609+
// current infoDictionary in case an error occurs again and we need
610+
// to re-recover.
611+
[infoDictionary setObject:invocation
612+
forKey:SSYAlertDidRecoverInvocationKey] ;
613+
}
614+
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
615+
recoveryOption:recoveryOption
616+
delegate:delegate
617+
didRecoverSelector:didRecoverSelector
618+
contextInfo:(__bridge void *)(infoDictionary)] ;
619+
}
620+
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:)]) {
621+
/* This is an error produced by Cocoa.
622+
In particular, in macOS 10.7, it might be one like this:
623+
Error Domain = NSCocoaErrorDomain
624+
Code = 67000
625+
UserInfo = {
626+
• NSLocalizedRecoverySuggestion=Click Save Anyway to keep your changes and save the
627+
changes made by the other application as a version, or click Revert to keep the changes from the other
628+
application and save your changes as a version.
629+
• NSLocalizedFailureReason=The file has been changed by another application.
630+
• NSLocalizedDescription=This document’s file has been changed by another application.
631+
• NSLocalizedRecoveryOptions = ("Save Anyway", "Revert")
632+
}
633+
*/
634+
NSInvocation* invocation = [error didRecoverInvocation] ;
635+
id delegate = [invocation target] ;
636+
SEL didRecoverSelector = [invocation selector] ;
637+
// I put the whole invocation into the context info, believing it to be alot cleaner.
638+
if (invocation) {
639+
// Before we invoke the didRecoverInvocation, we also put it into the
640+
// current infoDictionary in case an error occurs again and we need
641+
// to re-recover.
642+
[infoDictionary setObject:invocation
643+
forKey:SSYAlertDidRecoverInvocationKey] ;
644+
}
645+
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
646+
647+
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
648+
optionIndex:recoveryOptionIndex
649+
delegate:delegate
650+
didRecoverSelector:didRecoverSelector
651+
contextInfo:(__bridge void *)(infoDictionary)] ;
652+
}
653+
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:recoveryOption:)]) {
654+
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
655+
recoveryOption:recoveryOption] ;
656+
}
657+
else if ([recoveryAttempter respondsToSelector:@selector(attemptRecoveryFromError:optionIndex:)]) {
658+
// This is an error produced by Cocoa.
659+
NSInteger recoveryOptionIndex = [self recoveryOptionIndexForRecoveryOption:recoveryOption] ;
660+
[recoveryAttempter attemptRecoveryFromError:deepestRecoverableError
661+
optionIndex:recoveryOptionIndex] ;
662+
}
663+
else if (recoveryAttempter != nil) {
664+
NSLog(@"Internal Error 342-5587. Given Recovery Attempter %@ does not respond to any attemptRecoveryFromError:... method", recoveryAttempter) ;
665+
}
666+
}
667+
649668
- (IBAction)help:(id)sender {
650669
[[NSHelpManager sharedHelpManager] openHelpAnchor:[self helpAnchorString]
651670
inBook:[[NSBundle mainAppBundle] objectForInfoDictionaryKey:@"CFBundleHelpBookName"]] ;
@@ -753,7 +772,7 @@ + (void)supportError:(NSError*)error {
753772
and if it does, it will run a little prior to this one, in the same
754773
run loop cycle.
755774
*/
756-
- (IBAction)clickedButton:(id)sender {
775+
- (IBAction)clickedButton:(id)sender {
757776
// For classic button layout
758777
// Button1 --> tag=NSAlertFirstButtonReturn
759778
// Button2 --> tag=NSAlertSecondButtonReturn

0 commit comments

Comments
 (0)