@catch handler placed after a catch-all @catch (id)
ID |
objectivec.correctness.catch_handler_after_ellipsis |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Error Handling |
Language |
Objective-C |
Description
Reports an @catch clause written after @catch (id …) in the same @try. Only id is treated as the catch-all — a first handler typed NSException * is not, because an object of any class can be thrown. Handlers in a later @try, in a later method, or after @finally are not reported.
Rationale
@catch (id) accepts every thrown object, so no exception ever reaches a handler below it: the clause is dead code that reads as if it were live. Whoever wrote the specific handler expected it to run, and whoever reads the method later will believe that class of failure is handled — the recovery, the logging and the cleanup it contains simply never happen, and nothing at the call site says so.
The following code illustrates the pattern detected by this rule:
@implementation Importer
- (void)importOnSameLine:(NSData *)data {
@try {
[self decode:data];
} @catch (id anyError) {
[self log];
// FLAGGED: @catch handler placed after a catch-all @catch (id)
} @catch (NSException *exception) {
[self reset];
}
}
- (void)aLaterMethodWithItsOwnCatch:(NSData *)data {
@try {
[self decode:data];
} @catch (NSException *exception) {
[self reset];
}
}
- (void)decode:(NSData *)data { }
- (void)log { }
- (void)reset { }
@end