Error-Handling in Couchbase Lite for iOS

A common iOS error-handling pattern in Objective-C is to return a BOOL result and to pass an NSError by reference. In order to find out if the message had an error, you check the bool, and then if the method failed, you use the NSError object to find out why. In some cases, the NSError could contain garbage if you don’t check the BOOL first, so Apple recommends always checking the result before checking the NSError:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html

However, Couchbase Lite doesn’t always follow that approach. Consider CBLQuery.run, which takes an NSError reference and returns a CBLQueryEnumerator:
http://www.couchbase.com/autodocs/couchbase-lite-ios-1.0b2/interfaceCBLQuery.html#a6387c3a733c680447c8cd0dc0388af8d

There are reasons why you might pursue a different API style, but it would be nice if you were super-clear on the contract. Can we always rely on good values in the NSError object here, or do we need to check CBLQueryEnumerator first? I’m assuming not, since I don’t see a good way to check CBLQueryEnumerator for failure.

So I guess that to check for errors, you check the NSError first, and then check the CBLQueryEnumerator after that if the NSError shows no error?

We follow the Cocoa error-handling patterns.

return a BOOL result and to pass an NSError by reference.

It’s not necessarily a BOOL. Lots and lots of Cocoa methods return an object reference, so a nil result indicates an error.

Consider CBLQuery.run, which takes an NSError reference and returns a CBLQueryEnumerator: … I don’t see a good way to check CBLQueryEnumerator for failure.

No, this follows the same convention. The return type is CBLQueryEnumerator*, a pointer (or object reference). On failure it returns nil, then you check the NSError to see why.

Maybe you didn’t notice that CBLQueryEnumerator is an Obj-C class and is referred to by a pointer?

I did see that CBLQueryEnumerator is an Obj-C class, and I’ve seen the nil-check approach (although it feels far less common to me in Cocoa APIs anecdotally, and I don’t have a great way of analyzing all the APIs for frequency). Still, it does feel like good fit when you have a natural return value that isn’t a success/failure boolean, which in this case you do.

Since the error-handling approach wasn’t documented for the method, and I couldn’t find either a description or a really conclusive example of error-handling with CBLite and with the methods I was invoke in particular, I wasn’t sure what approach you were using. Thanks for clarifying which approach you’re using, this’ll help me handle errors properly. Is this covered already in the documentation and I just missed it, or is this something that’d be a valuable addition?

I don’t see a need to add explicit information about error handling because we’re not doing anything differently than usual. (I haven’t seen this sort of information in documentation of other 3rd party APIs. And no one’s asked about this before you did, in the 4 years that some version of Couchbase Lite has been available.)

Here’s the declaration of the closest equivalent method from Core Data, on NSManagedObjectContext. Note that it works exactly the same way as ours:

- (nullable NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error;

There are many other similar examples, from that class, NSFileManager, NSURL, etc.

You don’t see the need to document the behaviour of your API in your API documentation? Well … I’m not sure how to help you with that.

Notice in the Apple documentation you reference:

If an error occurs, returns nil. If no objects match the criteria specified by request, returns an empty array.

Similar phrases appear in the other APIs you reference here.

Assuming you do want your API documentation to document your API, this seems worth adding. It’s part of how the API behaves, it’s an extremely small addition, and similar documentation exists in other APIs.

Anyway – I have the answer I need, the documentation is up to Couchbase and I’ll move on.

I don’t see the need to add an explicit section of the developer documentation detailing error handling.

I do agree that it would be good to give each method’s doc-comment a full descriptions of parameters and the return value. A few methods have those already (search the headers for @return) and you’ll see that those comments describe the return values that indicate errors. I haven’t done this for the whole API mostly due to time constraints. To be honest, a lot of developers don’t seem to look at the doc-comments at all…