1

Is it a good practice to subclass from NSException for app-specific exceptions? That way everything is centralized one class for easier management.

e.g.

@interface AppException : NSException

+ (AppException *)InvalidSomething;
+ (AppException *)InvalidSomething2;

@end
Adam
  • 26,549
  • 8
  • 62
  • 79
Boon
  • 40,656
  • 60
  • 209
  • 315

1 Answers1

4

No, it's not good to subclass NSException because it's a class that doesn't need to be any more specific than it already is. In addition, subclasses, as is noted in the documentation, may not receive proper call stack symbols if thrown:

NSException subclasses posing as the NSException class or subclasses or other API elements that interfere with the exception-raising mechanism may not get this information.

If you wish to have "predefined exceptions" to throw, you can write a macro on NSAssert.

#define BOAssert NSAssert(0, @"Something bad just happened");

If you need "application-specific exceptions," make a constant that you can pass to +raise:format:. Bear in mind, though, that Objective-C is not Java. Exceptions are not a means of control flow, and should never be used as such (nothing in Cocoa-Touch can be regarded as exception safe). Because exceptions are fatal, give serious thought to why you'd actually need to throw them, and in what situations -for example, UITableView throws exceptions when it is updated into an undefined state.

CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • I agree on your point but it seems to be useful to centralize the management of app exceptions in one place. I don't understand the suggestion on NSAssert since they are two totally different things. – Boon Jan 30 '13 at 23:10
  • @Boon Asserts throw exceptions, they aren't "totally different things", and they're far more efficient (syntax-wise) than allocating and throwing an NSException. – CodaFi Jan 31 '13 at 01:42
  • The underlying mechanism may be the same, but the intent is different and will affect code reading. Using NSAssert to get exception seems inferior to creating a class to throw an exception, at least with a class you can do other things like log the exception to a file. – Boon Jan 31 '13 at 01:53
  • Thanks for including the NSException subclass excerpts, very informative. – Boon Jan 31 '13 at 01:54
  • Well, then it's a tradeoff: Either you get unstable call stack symbols, or you get no output to file. – CodaFi Jan 31 '13 at 02:42
  • To be absolutely clear, Exceptions should not be used to handle recoverable errors. You should not be throw'ing and then catch'ing and continuing execution. – bbum May 20 '13 at 15:44
  • @bbum It's a salient point (and I always greatly appreciate backing from such a prominent engineer), but doesn't Core Data use exceptions for control flow? ;) – CodaFi May 20 '13 at 16:27
  • @CodaFi Yes and they get away with it because they have the source. And it is a source of pain. – bbum May 20 '13 at 16:39