Custom Errors in Objective-C

In Objective-C, we can create custom error types by implementing the NSError class. Here’s an example that demonstrates how to create and use custom errors:

#import <Foundation/Foundation.h>

// A custom error domain
static NSString *const ArgErrorDomain = @"ArgErrorDomain";

// Error codes for our custom error
typedef NS_ENUM(NSInteger, ArgErrorCode) {
    ArgErrorCodeInvalidArgument = 1
};

// A function that may return an error
NSInteger f(NSInteger arg, NSError **error) {
    if (arg == 42) {
        // Create and return our custom error
        if (error != NULL) {
            NSDictionary *userInfo = @{
                NSLocalizedDescriptionKey: @"can't work with it",
                @"arg": @(arg)
            };
            *error = [NSError errorWithDomain:ArgErrorDomain
                                         code:ArgErrorCodeInvalidArgument
                                     userInfo:userInfo];
        }
        return -1;
    }
    return arg + 3;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSError *error = nil;
        NSInteger result = f(42, &error);
        
        if (error) {
            NSLog(@"Error: %@", error.localizedDescription);
            NSLog(@"Argument: %@", error.userInfo[@"arg"]);
        } else {
            NSLog(@"Result: %ld", (long)result);
        }
    }
    return 0;
}

In this example, we define a custom error domain ArgErrorDomain and an error code ArgErrorCodeInvalidArgument. The function f returns an NSError when the input argument is 42.

The main function demonstrates how to use this custom error:

  1. We call the function f with an argument of 42, which should trigger our custom error.
  2. We check if an error was returned.
  3. If an error occurred, we print the error description and the argument that caused the error.

When you run this program, it will output:

Error: can't work with it
Argument: 42

This approach allows us to create rich, custom errors with additional information (stored in the userInfo dictionary) that can be useful for debugging or providing more context about the error.

In Objective-C, we use NSError objects to represent errors, which is different from Go’s error interface. However, the concept of creating and using custom errors is similar in both languages.