Re: NSError: why returned directly?
Re: NSError: why returned directly?
- Subject: Re: NSError: why returned directly?
- From: William Bumgarner <email@hidden>
- Date: Wed, 26 Apr 2006 08:58:21 -0700
On Apr 26, 2006, at 8:11 AM, Jonathon Mah wrote:
The whole error/exception distinction currently in Cocoa feels too
hazy. What divides programmer errors and runtime errors? Erik
suggests an illegal array index is a runtime error, but I shudder
at the thought of [array objectAtIndex:error:].
An array has a -count that explicitly exists both for checking
content quantity in the array and to ensure that you don't walk off
the end.
The Foundation's API contract is such that an index out of range
error is considered to be a programmer error.
Ondra raises some good points. Using @throw for errors would avoid
the manual stack unwinding. It could also give you a nicer way to
hook into errors in the debugger; breaking on -[NSException raise]
is easy, but is there any way to break on an error?
Using @throw to handle errors requires lots of @catch/@finally blocks
to manage memory and otherwise deal with exception based error
handling. Since an @throw can jump frames on the stack, you have to
be very sure that program state is as expect in the @catch/@finally
block. With NSError based returns, returning in an error condition
must follow the same return path -- go through the same stack frames
-- as returning a success condition (internally, of course, an error
condition will cause different code paths to be exercised).
Generally, you can break on NSError's instantiation methods:
- (id)initWithDomain:(NSString *)domain code:(int)code userInfo:
(NSDictionary *)dict;
+ (id)errorWithDomain:(NSString *)domain code:(int)code userInfo:
(NSDictionary *)dict;
Finally, a question about error style: If a method succeeds and an
error parameter was passed in, should the error parameter be set to
nil or left unchanged?
Left unchanged. This is the one key area that developers screw up
pretty consistently when first faced with NSError**. The rules:
1. Do not allocate an error object when calling a method that takes
an error parameter. Just pass a pointer to an uninitialized NSError
* variable.
NSError *foo;
BOOL success = [bar doSomething: &foo];
2. if a method returns success, do not touch the error parameter.
if (success)
// goody -- don't touch foo
3. if a method returns failure, the error MUST be set to something
valid.
if ( !success )
... assume foo is set to a valid NSError ...
4. when writing a method that takes an NSError** parameter, always
check to see if the error parameter is non-nil before trying to stuff
an error into it.
if (error)
// set error here
5. when writing a method that takes an NSError** parameter, never
*never* return nil/no/failure and *not* also set the error parameter
(after applying #4)
if (booBooOwy) {
if (error) {
*error = [NSError ...
}
return NO;
}
Finally, if you are creating new Objective-C APIs, I would very
strongly discourage you from using NSExceptions to indicate anything
but programmer error or other internal assertions. Like it or not,
NSError based indication and handling of runtime errors is the design
pattern used throughout AppKit and Foundation. If you think that
using NSExceptions internally is a good idea, you are in for some
pain at the point in time you decide to to expose previously
unexposed API.
b.bum
_______________________________________________
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