Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What’s the rationale behind the Cocoa exception policy - or why use exceptions only for programmer errors?

What’s the rationale behind the Cocoa exception policy - or why use exceptions only for programmer errors?

I understand that exception used to be rather expensive so one would not want to overuse them. But that changed with the modern runtime and it’s zero-cost exceptions. I also understand that the use of exceptions to do general control flow is not a good idea because it could lead to code that is rather hard to understand.

But why should one use exceptions to signal programmer errors? For that case logging a message followed by abort() should be enough. Why should I write a @catch(...) block to handle a programmer error instead of fixing the actual mistake? I’ve been thinking about this a lot and I haven’t found any reasonable use of an exception for a programmer error.

(As a side note/question: I’ve written a recursive descent parser, and I’m planning on using exceptions in there for handling errors. Seems to be much more reasonable to me than adding an out parameter to every single function in there and manually check for an error everywhere. Of course I’ll catch any exceptions I throw in the top level methods that get called from the outside. Anyone think that’s a bad use for exceptions?)

Update: The real question

Thanks for all the answers so far. They all are true, but they don’t actually answer my question. So I guess I wasn’t really clear about it, sorry for that. So here’s the real question:

Why does Cocoa throw exceptions for programmer errors (or assertions) at all? One isn’t supposed to catch them, and actually writing code that handles a programmer error somewhere down the call stack is not a good idea anyways. Seems to me that exceptions there are a wasted effort. Simply logging the error and calling abort() (which exits the program) should be enough. So what’s the advantage there of actually having an exception thrown?

I understand why exceptions are not generally used and discouraged - most parts of Cocoa are just not exception safe. And that’s not the question here. I hope I made this clear now.

like image 543
Sven Avatar asked Sep 28 '10 10:09

Sven


3 Answers

Why should I write a @catch(...) block to handle a programmer error instead of fixing the actual mistake?

In most cases, you wouldn't. In Objective-C, you generally don't handle exceptions. If an exception occurs, it causes a crash, and then you fix the bug -- hopefully you catch this during testing.

Of course, in some cases this doesn't work out. Maybe you do except an exception and you can workaround it, so you catch it. Or there's there rare API that'll throw exceptions instead of using error objects.

To be honest, I very, very rarely use try/catch in my Objective-C code.

As for the rationale, I think it's largely due to Objective-C's C heritage. Back in the early 80s when Objective-C was developed, exceptions were kind of "new" (i.e., not in many mainstream languages yet), and Objective-C catered more to the C tradition of using NULL or an out parameter to signal errors.

like image 90
mipadi Avatar answered Sep 21 '22 04:09

mipadi


Your question explicitly assumes that "one isn’t supposed to catch them." This is incorrect. The programmer isn't expected to catch them under normal circumstances, but that isn't to say that they must never be caught for any purpose.

Example: I'm not sure if it does anymore since it's much less buggy these days, but I know it at least used to be the case that Xcode would catch exceptions and put up a dialog saying, "Such-and-such happened. It doesn't appear to be a critical problem, but you should probably save and restart the program to avoid any trouble in the future."

like image 37
Chuck Avatar answered Sep 20 '22 04:09

Chuck


Why does Cocoa throw exceptions for programmer errors (or assertions) at all? One isn’t supposed to catch them, and actually writing code that handles a programmer error somewhere down the call stack is not a good idea anyways

Ah!

Three reasons leap to mind.

One, if you catch an exception more or less at your main run loop you could autosave state to a temporary location, crash, and on restart have a "try to restore from just before the crash, warning: may cause another crash and you should check your data very carefully" dialog/sheet/thingie. Or even just catch the exception and tell the user to do a "Save As", quit and restart.

Two, things like the unit test framework make good use of exceptions to abort the current test (logging a failure), and continuing with the rest of the tests. This lets you see if a change you made has one regression (that happens to index a NSArray out of bounds), or if you have six regressions (one or more of which throw an exception).

Three, maybe when added to ObjC it was intended to handle many kinds of errors with exceptions, and after real world experience the useful scope was determined to be "nearly fatal errors only".

like image 23
Stripes Avatar answered Sep 21 '22 04:09

Stripes