NSError** is hard

Bill Bumgarner / @bbum:

NSError** is hard http://tinyurl.com/yzvpmxr (it really is hard — would be nice to make this easier in the future)

The url expands to a Stack Overflow question where Bill rewrites some code to check a method’s return value before checking its returned-by-reference NSError. He writes:

You must not assume anything about the return-by-reference value of fileError until you check whether or not fileContents was nil. Not ever. Setting fileError to nil prior to calling the pass-error-by-reference method does nothing useful.

Johan Kool provides a reference link:

Important: Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.

I really chafe at this don’t-nil-out-NSError-and-treat-it-as-radioactive-unless-return-value-indicates-an-error pattern.

What’s wrong with setting NSError* to a known-good state and possibly testing it afterwards? Bill’s must not assume language makes it sound like methods may upturn-the-table upon encountering error conditions and do wacky things like set NSError* to an invalid address.

I’d classify that as a bug, not an error-handling pattern.

I’d love to hear a concrete scenario or two why I should never look at a pre-set NSError* unless I detect an error through a return value.

Update: It is as I feared. Bill Bumgarner / @bbum:

@rentzsch There are methods that very much do scribble on the error argument, if non-NULL, and will not reset-to-NULL on success.

I go out of my way to not expose such behavior in the code I write, but apparently Apple has a different philosophy on the matter. I disagree with it, but my code has to waltz with their code, so they win.

cocoa objc nserror software-quality Nov 27 2009