Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create custom exception in objective c?

I am trying to achieve something like this in objective c.

@try{
//some code that will raise exception
}
@catch(CustomException e){//How to create this
//catching mechanism
}
@catch(NSException e){
//Generic catch
}

I need to create CustomException class and use it. Could you please help me in creating this CustomException and guide me in how to use this.

Thanks in advance.

like image 494
Easwaramoorthy K Avatar asked Jul 15 '12 15:07

Easwaramoorthy K


People also ask

How to handle exception in Objective C?

Exception handling is made available in Objective-C with foundation class NSException. @try − This block tries to execute a set of statements. @catch − This block tries to catch the exception in try block. @finally − This block contains set of statements that always execute.

What is NSException?

An object that represents a special condition that interrupts the normal flow of program execution.


2 Answers

Exceptions are very rarely used for control flow like this in Objective-C. I'm guessing you have a Java (or similar) background.

I'm not saying that you can't write code like this but it will feel very strange for other people looking at your code and could also possibly work badly if used by other peoples code if you don't completely isolate the exceptions so that it never reaches their code.

How it is commonly done in Objective-C

Exceptions are used for critical errors. If the error is expected (like it seems to be since you want to @try it) you should instead try and return an NSError. This is a design pattern that is used all over the Foundation and Cocoa frameworks and also third party frameworks. Look for example at networking, file reading/writing or JSON code (JSONObjectWithData:options:error:)

What you would do

What you do is add a error parameter (double pointer) at the end of your method that could fail, like this:

- (MyResultObject *)myMethodThatCouldFailWith:(MyObject *)myObject
                                        error:(NSError **)error;

When someone (you or someone else) uses this method they can if they want to pass a NSError pointer that will get set if an error occurred, like this:

NSError *error = nil; // Assume no error
MyResultObject *result = [self myMethodThatCouldFailWith:myObject
                                                   error:&error];
if (!result) {
    // An error occurred, you can check the error object for more information.
}

Note the ampersand (&) before the error parameter. This means that you are sending your error points as the argument so that inside the risky method that pointer can be changed to points to a new NSError object which can be read after the method returns.

Now, inside your method that could fail, you would set the error to a new NSError object if something went wrong (instead of raising an exception). It is also very common to return nil when an error occurs since that probably means that the calculation won't be able to complete or that the data is unreliable or irrelevant.

- (MyResultObject *)myMethodThatCouldFailWith:(MyObject *)myObject
                                        error:(NSError **)error {
    // Do something "risky" ...
    MyResultObject *result = [MyResultObject somethingRiskyWith:myObject];
    
    // Determine if things went wrong
    if (!result) {
        // Set error if a pointer for the error was given 
        if (error != NULL) {
            *error = [NSError errorWithDomain:yourErrorDomain
                                         code:yourErrorCode
                                     userInfo:optionalDictionaryOfExtraInfo];
        }
        return nil;
    }
    
    // Everything went fine.
    return result;
}

Now if the error returns you can identify what kind of error it was from the error code that you specified and you can read more detailed information in the user info dictionary (where you can add lots of information).

like image 62
David Rönnqvist Avatar answered Oct 18 '22 10:10

David Rönnqvist


In the simplest case, I can declare a class using...

@interface CustomException : NSException
@end
@implementation CustomException
@end

...and the code is very much like what you posted:

   @try{
        @throw [[CustomException alloc] initWithName:@"Custom" reason:@"Testing" userInfo:nil];
    }
    @catch(CustomException *ce){
        NSLog(@"Caught custom exception");
    }
    @catch(NSException *e){
        NSLog(@"Caught generic exception");
    }
like image 33
Phillip Mills Avatar answered Oct 18 '22 11:10

Phillip Mills