CSC/ECE 517 Fall 2009/wiki1b 3 expHandle

From Expertiza_Wiki
Revision as of 00:01, 22 September 2009 by Maverick (talk | contribs)
Jump to navigation Jump to search

Describing the exception handling concepts in various Object Oriented Languages and pointing the nuances of difference in their implementation

Introduction

Exception Handling

Every functionality or use case in any application can have multiple outcomes. Depending on the result of the operation performed we have a happy flow, error flow or exception flow. The exception flow is triggered when some unexpected or unusual flow is initiated. This can be due to failure of external system failure or some unexpected user inputs. This can also be due to bad coding practices followed by the developer. Every language has some support for this kind of exception scenario. Either the exceptions are handled, thrown or initiated in a method. The mechanism differs in different languages, like in some languages like Java the entire cause of exception is made available till the point the exception is interpreted into a response, in languages like C’s atoi (ASCII to Integer) function the response if zero (0) even if the parsing fails, thus making it difficult to distinguish between a correct parsing of 0 or a parsing failure error.

Scope

Here let’s try and understand the way Exception Handling is implemented in various languages and then compare them based on

1) Ease of development

2) Simplicity on understanding

3) Resources freeing up (You will definitely want your code to close/release the file it tried to open or close a db Connection to the pool)

4) Error handling and transporting

Exception Handling in Perl 5

Legacy Perl (Perl 5.5 and earlier) is being discussed about and illustrated here. The newer advances and modules added in Perl 6 and the fix done on the issues (memory leak fixes for instance) is not been described here. Perl technically has a support for error handling rather than exception handling. They eval function is used to check for errors and the based on the status of "$@" variable the error handlers where written. The below code sample shows a sample implementation of this:

eval{
   #do some process 
   # do some more code
 };
 if ($@ == err1) {
   errorHandler1($@);
}if ($@ eq err2){
   errorHandler2($@);
}

The code eval function in case of an exception populates the $@ variable with the error message and terminates the execution of the script and transfers the control to line immediately after the eval block. In case of success, the $@ variable is assured of having a null string value The issue with this way of implementation is that the value variable $@ which is a scalar variable, can be easily changed either knowingly or accidently by the programmer. To add to it, the $@ variable is a global variable so the error information is available even in places where there exception should not have been transmitted as an exception. Also in case if one of the error code values is not checked for then that error goes unhandled and the correct information is not processed. This way of error handling also fails to give the location/trace of the exception making it difficult to ascertain the root cause. There was another way of implementation in Perl 5.005. In this way one could create a custom exception class and also invoke its method using the same syntax as in the earlier case.

eval{
   ....
 };
 if ($@) {
   if ($@->isa('MyFileException')) {  # Specific exception handler
     ....
   }
   else { # Generic exception handler
     ....
   }
 }

This also left some of the issues still unaddressed which are listed below: eval blocks can be used for both, building dynamic code snippets as well as for exception handling. Hence can be confusing to look at and figure out the purpose on an eval block

No built in provision for cleanup handler a.k.a finally block. Hence may involve repetitive lines of code of same purpose.

Stack trace if required, needs to be maintained by writing custom code.

To handle the issues, the CPAN (Comprehensive Perl Archive Network) added two modules Error.pm and Exception::Class. The Error.pm is used in approximately 80 CPAN distributions and Exception::Class in 60 CPAN distributions. Following is the code example illustrating the use of the Error.pm module.

 use Error qw(:try);
 try{
   some code;
   code that might thrown an exception;
   more code;
   return;
 }
 catch Error with {
   my $ex = shift;   # Get hold of the exception object
   handle the exception;
 }
 finally {
   cleanup code;
 };

This implementation style is similar to JAVA. The first code line indicates that the particular class will be using the Error.pm module and the :try implies that the various modules for performing exception handling will be referenced and used. In this case the try block executes the code and exception if any will be caught in corresponding catch block. The catch block catches the corresponding exception. It internally invokes the ISA operation. The order of the catch block is important in the sense while catching the child exception class’s catch block should be first and then up the hierarchy to parent. There are two arguments that are sent to the catch block, one the exception and the second one isa scalar reference. If the scalar reference is set in the catch block, then the try block will treat the return from the catch block as if there is no error that has occurred. If the scalar variable is not set and the error is not thrown from catch, then the try block will return the result returned by the catch block. The finally block is the missing clean up block. The finally block is executed during the successful try processing and during an error scenario. There are two more blocks in the error handling mechanism “except” and “otherwise” block. The except block if found by the try block will be used to process the errors. The return value from this block should be a HASHREF or a list of key-value pairs, where the keys are class names and the values are CODE references for the handler of errors of that type. The otherwise block will catch any error that occurs in the try block. The only argument passed to this block is the type of error being processed. The exception handling mechanism provides a throws clause that allows one to raise an exception. The clause can be invoked from anywhere in the code. In case the try block is missing in the calling hierarchy, then the program will be terminated.