A reminder to myself around where and when to use NSError vs throwing exception in Objective-C.

This article gives a nice summary


Use NSError for Most errors

When things go wrong in your app, due to

x network connectivity
x database been down etc

Use NSError and pass errors by reference.

- (BOOL)writeToURL:(NSURL *)aURL
 error:(NSError **)errorPtr;

Create an error pointer/reference and pass it to your method

NSError *anyError;
BOOL success = [receivedData writeToURL:someLocalFileURL options:0

if (!success) {
 NSLog(@"Write failed with error: %@", anyError);
 // present error to user

The recover if possible and display an error to the user.

Generating your own errors

To create your own error define your own error domain.


Along with a unique error code for each error that may occur.

NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";
 NSString *desc = NSLocalizedString(@"Unable to…", @"");
 NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
 NSError *error = [NSError errorWithDomain:domain

Then use as follows

- (BOOL)doSomethingThatMayGenerateAnError:(NSError **)errorPtr;

- (BOOL)doSomethingThatMayGenerateAnError:(NSError **)errorPtr {
 // error occurred
 if (errorPtr) {
 *errorPtr = [NSError errorWithDomain:...
 return NO;

Exceptions are Used for Programmer Errors

- (void)testInvalidUrl {
 XCTAssertThrows([self.player playURL:@"foobar" error:NULL], @"Invlaid url.");

- (BOOL)playURL:(NSString *)url error:(NSError **)errorPtr {
 if ([url containsString:@"track"]) {
 return [self.handler playTrack:url error:errorPtr];
 } else if ([url containsString:@"album"]) {
 return [self.handler playAlbum:url error:errorPtr];
 } else {
 [NSException raise:@"Invalid url" format:@"%@ must be a track or an album.", url];
 return NO;