Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing list of error codes for NSError in objective c

In Cocoa and Objective C the favorite method for managing error seems to be using an NSError * object, to construct an error object however, we need to call the following method

+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict

My question is, what are some of the best practices for managing error domain, error code definitions and user info dictionary across the entire application so that error code, domain and user info dict always stays consistent?

like image 968
Tony Avatar asked Feb 12 '12 02:02

Tony


People also ask

How do you handle errors in Objective C?

In Objective-C programming, error handling is provided with NSError class available in Foundation framework. An NSError object encapsulates richer and more extensible error information than is possible using only an error code or error string.

What is NSError code?

Like exit status codes, an NSError -code signals the nature of the problem. These status codes are defined within a particular error domain , in order to avoid overlap and confusion. These status codes are generally defined by constants in an enum .

What is NSError domain?

The core attributes of an NSError object—or, simply, an error object—are an error domain, a domain-specific error code, and a “user info” dictionary containing objects related to the error, most significantly description and recovery strings.


2 Answers

If you have a hefty amount of error construction, your life could be much simpler by using a class. I actually use C++ for this so the calls a program does not need may be removed (unlike objc), but you can use C, ObjC, or C++ for this:

MONErrorDomain.h

// you won't normally need an instance here
@interface MONErrorDomain : NSObject

+ (NSString *)domain; // << required override
- (NSString *)domain; // << returns [[self class] domain]

// example convenience methods:
// uses [self domain]
+ (NSError *)errorWithErrorCode:(NSInteger)errorCode; // << user info would be nil
+ (NSError *)errorWithErrorCode:(NSInteger)errorCode userInfo:(NSDictionary *)userInfo;

@end

MONKoalaError.h

@interface MONKoalaError : MONErrorDomain

+ (NSError *)outOfEucalyptus;

@end

extern NSString * const MONKoalaErrorDomain;

typedef enum MONKoalaErrorCode {
  MONKoalaErrorCode_Undefined = 0,
  MONKoalaErrorCode_OutOfEucalyptus
} MONKoalaErrorCode;

MONKoalaError.m

// apple recommends we use reverse domains
NSString * const MONKoalaErrorDomain = @"com.mon.koala-library.MONKoalaErrorDomain";

@implementation MONKoalaError

+ (NSString *)domain
{
  return MONKoalaErrorDomain;
}

+ (NSError *)outOfEucalyptus
{
  NSDictionary * info = …;
  return [self errorWithErrorCode:MONKoalaErrorCode_OutOfEucalyptus userInfo:info];
}

@end

Then the error creation is all in one place for each domain, and the clients can easily pick their errors without actually building them manually:

if (outError) {
  *outError = [MONKoalaError outOfEucalyptus];
}

and error handling takes the form:

if ([e.domain isEqualToString:MONKoalaErrorDomain]) {
  switch (e.code) {
    case MONKoalaErrorCode_OutOfEucalyptus : {
      self.needsEucalyptus = true;
…
like image 124
justin Avatar answered Sep 20 '22 00:09

justin


One common way is to define some appropriate constants in a header file, and then include that header file wherever needed. It's a pretty simple approach, and looks like:

const NSString * kMyAppErrorDomain = @"com.example.myapp";
const NSInteger kMyAppSomeError = 2;

// key into user info dictionary
const NSString * kMyAppProblemKey = @"MyAppProblemKey";

I've also seen some applications which create convenience methods for creating these, either as a category on NSError or as a separate utility class or set of functions. It's also entirely reasonable to subclass NSError, for example to customize the localized description.

If you have not already seen it, Apple has released the Error Handling Programming Guide which discusses how these should be used in Cocoa.

like image 29
Jeremy Roman Avatar answered Sep 19 '22 00:09

Jeremy Roman