Re: NSError: why returned directly?
Re: NSError: why returned directly?
- Subject: Re: NSError: why returned directly?
- From: Ali Ozer <email@hidden>
- Date: Wed, 26 Apr 2006 20:42:27 -0700
Ali,
thank you very much for a detailed answer. Please, allow me a few
more questions to tie loose ends:
On 26.4.2006, at 17:56, Ali Ozer wrote:
- Historically the way exceptions have been handled. There is not
too much exception-clean code out there, so exceptions are likely
to lead to leaks and other loose ends. In fact, our general
recommendation is if a programmer-error exception is encountered by
the end-user, that they go ahead and try to save and quit as soon
as possible.
Are they some issues with exceptions, why this should apply in
general, for any application? Do exceptions tend to leave a mess on
stack in some special situation, or whatever?
(Apart of the self-evident "exception may occur anytime, so I either
have to autorelease anything, or catch&release in @finally/
NS_HANDLER", which of course my code is aware of for years :))
Namely, considering your previous answer, I am about to turn to the
convention of @throwing NSError in my own code, and am, actually,
asking for reason why I should not :)
If you are happy with the exception handling abilities of your code
and any other code on the stack, then it might work fine. I was
referring to the fact that much code not written to be fully exception
clean. In most cases I would guess the main problem will be leaks.
- Our guidelines state that NSError should be used for problems
that need to be reported to the user. And we would like to see that
done very well --- that the user gets a clear statement of what
went wrong, and why, with a possible recovery suggestion. And as
you know Cocoa has APIs to help automate the presentation as much
as possible.
Yup -- actually, one of goals of my recommendation (along with a
global exception handler doing an [NSApp presentError:] when an
NSError is catched) was to make this to work as well as possible
*even if the programmer does not care at all*. In the current
system, the programmer still must support it explicitly so as the
error reporting works at all (albeit the Cocoa help is huge, of
course, and the remaining programmers' task comparatively small).
But in the exception scenario, if the programmer doesn't care at all,
he is likely to have lots of code which is not exception clean; so
even though he will get proper error reporting, the code will be
bypassing certain calls in unpredictable ways and leaving untied loose
ends behind. My main objection with this approach for error handling
is that any line of code can now "return an error" --- by throwing an
exception. If not today, maybe in the future. Managing that to be
exception clean is not a trivial task. For someone who always writes
100% exception clean code this isn't a problem (but even there the
intermediate layers you don't own might bet trouble), but very little
code out there is 100% exception clean. And for us to introduce such a
mechanism generally into Cocoa would mean we expect all Cocoa and
third party code to be well-behaved.
Given this, rather than sprinkling errors across a vast number of
methods, we would rather put them on select, well thought out
methods whose results are important to bubble up to the user. So
hopefully we're not attaching NSError arguments to every single
method, but just those cases where they're useful and needed.
Therefore the burden shouldn't be huge.
This I do not quite get: perhaps I am overlooking something of great
importance, but it seems to me that
(a) any method which can fail due to external causes is a very good
candidate for an NSError;
(b) any method which calls any other method which already is NSError-
aware just has to chain it up explicitly (*), becoming NSError-aware
itself (actually, this fact was the rationale behind my exception-
mechanism suggestion).
(*) unless such a method would presentError, of course; that may
occur in AppKit perhaps sometimes, but hardly ever in Foundation.
It seems to me (a) makes for comparatively big number of methods
(more or less whatever which works with any external resource, be it
disk, network, some authorisation system, almost anything), and (b)
ensures it would spread like a forest fire :)
Am I wrong in this? What am I overlooking here? Does your "useful
and needed" translate to there will always be a huge number of
methods which will just fail returning nil (or NO or something
similar) without a possibility to report the precise cause by an
NSError (leaving the burden of determining why they failed on
programmer), which would alleviate my (a)? Or have I overlooked
something which makes (b) not true?
(a) and (b) are often true, but in the end, a large percentage of
methods don't fall into (a). Clearly NSData, NSDocument, etc have a
lot of (a), but something like NSTableView not.
- We also have the guideline of passing NULL in as the (NSError **)
argument, which both makes it easier for the caller if for some
reason they don't need to know error details, and more efficient
for the callee if they take care not to create an NSError in that
case. The reason I mention this is that even though there is an
explicit error argument, ignoring the error is pretty easy, if
desired.
Agreed. Have you found, though, in Apple code, you often ignore
possible causes of error?
It's not often, but there are times when the caller just needs to know
failure, because the caller will in turn maybe try something else or
create her own error message.
Ali
From the moment I have begun used NSError extensively (10.4, for the
previous thing was severely limited), I've found I've ignored the
error quite rarely, and even that tends to be only in a test/non-
production code where the only reason to ignore was my laziness :)
Thank you again for your time,
---
Ondra Čada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden