Exception Handling

Document Sample
Exception Handling Powered By Docstoc
					                      Exception Handling
•   Exception handling (EH) allows a programmer to provide code in the
    program to handle run-time errors or exceptional situations
    –   this improves reliability
•   EH was first introduced in PL/I and found in few languages
    (except for EOF-types of mechanisms) until C++
    –   EH has been included in most modern languages since C++ since their
        utility greatly improves reliability
•   Here, we look at PL/I, Ada, C++ and Java and briefly consider
    Events as a special form of exception
    –   design issues:
         •   how/where are exception handlers specified and what is their scope?
         •   how is an exception bound to a handler?
         •   where does execution continue after the handler executes (continuation)
         •   how are user-defined exceptions specified, if at all?
         •   are there predefined exceptions? If so, should there be default handlers for
         •   can predefined exceptions be explicitly raised?
         •   are hardware errors treated as exceptions to be handled?
         •   should it be possible to disable predefined exceptions?
             Binding and Continuation

Exception handler binding determines which handler can handle the exception

Continuation determines what happens after the handler executes:
         return to the same statement that raised the exception (or the next one) end the
         block that contains the instruction that raised the exception terminate the program
• User-defined exception handlers can appear anywhere in the program (see
    – condition is a pre-defined or user-defined exception
         • two built-in conditions are ANYCONDITION and ERROR
    – user-defined exceptions work as follows:
         • ON CONDITION (boolean)
    – SNAP is a keyword to print out dynamic chain
• Reference environment is the code in which handler is embedded
• Binding is dynamic: the handler is bound to the exception from the ON
  statement until either
    – a new handler is defined
    – the end of the local block is reached
    – a revert statement is reached
• Built-in exceptions all have built-in handlers but can be overridden by user-
  defined handlers
    – you can enable or disable conditions (some default to being disabled)
         • (NO condition) : statement; or
         • (condition) : statement;                             General form:
• Continuation can be                                            ON condition [SNAP]
    – a branch (using GO TO)                                     BEGIN;
    – continue with the same or next instr.                             …
    – termination of program                                     END;
                              PL/I Examples
                                                In the example below, handlers for
                                                Endfile are provided for two different files

Above, SIZE is enabled, from the On
instruction forward, a handler is defined for    Built-in exceptions include ENDPAGE,
any SIZE error (the error handler simply         ENDFILE, CONVERSION, OVERFLOW,
does “SNAP”). The SIZE error handler             UNDERFLOW, ZERODIVIDE, SIZE,
continues to Operate in B, C, D and E            STRINGRANGE, SUBSCRIPTRNAGE,
because of dynamic binding (even though          UNDEFINEDFILE
only C is inside of B’s static scoping)
• Ada exception handlers are defined using the following syntactic
   – when exception_choice { | exception_choice} = > statements
   – when is a reserved word
   – exception_choice is a pre-defined exception type or one defined by the
     programmer, and statements is a list of statements
   – other is an acceptable choice for exception_choice meaning that this is a
     default handler for all types of exceptions that do not have specific
• Handlers are defined in a separate exception portion of a block of
  code as shown below
   – they can also be listed outside of a subprogram but inside a package
                … code here that can raise exceptions to be handled
                when exc_name1 => handler code here
                when exc_name2 => handler code here
                      Binding in Ada
• Which handler is executed when an exception arises?
   – if the block of code has an exception handler for the exception,
     then the exception is statically bound (that is, the handler in
     that block is used)
   – otherwise, the exception is propagated as follows:
      • if raised in a procedure, exception is propagated to the calling
        subprogram at the point of the call
          – if that subprogram has no handler, the exception is propagated to its
            caller, etc until the exception reaches the main program in which case it is
            either handled there (if there is a handler) or the program terminates
      • if raised in a block, the exception is handled by the procedure that
        contains the block (an example of this follows), and if there is no
        handler, the exception propagates as described above
      • if raised in a package body, then the handler of the package is used and
        if there is none, then it is propagated to whatever unit contains the
        package declaration
          – if this is a library, then the program terminates
          – if the package defines the main program (e.g., not used by another) then
            the exception is ignored and execution continues!
                        Ada Continued
• The block or procedure that raised the exception will be
  terminated automatically
   – continuation after exception handling either results in termination of the
     program if there is no handler, or
   – control returns to the body that invoked the unit that raised the exception
       • if Main calls Sub1 and Sub1 raises the exception, after handling, control
         resumes with the instruction in Main after the call to Sub1
       • if an exception is raised in a loop, the loop body is terminated, control
         resumes with the loop control (the loop may be re-entered if the loop
         condition is true)
• Other info:
   – exceptions (conditions) can be explicitly disabled
   – there are 5 built-in exception categories:
       •   constraint
       •   program
       •   numeric
       •   storage
       •   tasking
   – programmers can define further exceptions
   – exceptions can be raised explicitly through
       • raise exception_name
                              Ada Example
                                                                    when End_Error =>
                                                                    Put(“Limits Frequency”);
with Ada.Text_IO, Ada.Integer.Text_IO;
                                                                    for Index in 0..9 loop
use Ada.Text_IO, Ada.Integer.Text_IO;
                                                                      Limit_1 := 10 * Index;
procedure Grade_Distribution is
                                                                      Limit_2 := Limit_1 + 9;
  Freq : array(1..10) of Integer := (others => 0);
                                                                      if Index = 9 then
  New_Grade, Index, Limit_1, Limit_2 : Integer;
                                                                         Limit_2 := 100;
                                                                      end if;
      Index := New_Grade / 10 + 1;
         Freq(Index) := Freq(Index) + 1;
                                                                    end loop;
                                                                end Grade_Distribution;
             when Constraint_Error =>
               if New_Grade = 100 then Freq(10) := Freq(10) + 1;
                  else Put_Line(“Error – new grade is out of range”);
               end if;
     end loop;
• Not implemented until after 1990
   – handlers are placed in catch blocks following try blocks
   – if an exception arises in the try block, control can be thrown to
     the associated catch block
      • if the code is not in a try block, any exception will not be handled
   – try and catch blocks are embedded within other code, such as a
     block or inside a function
      • example: try { … code with exception … }
                 catch (params) {…}
                 catch (params) {…}
   – exceptions can only be raised using an explicit throw statement
     as in throw (params);
      • NOTE: a throw statement without parameters is possible but only in a
        handler, the result is that the handler re-invokes itself
   – the type(s) of parameter(s) determine which catch is used
      • for instance, throw(x); where x is an int will be caught by a catch(int p);
        but not by a catch(float p);
                           More on C++
• If an exception is raised in a try block, the block terminates and
  control goes to the proper catch
   – catch blocks are checked in order
       • so for instance, if there are two catch blocks that catch an int, the first will be
         the only one to ever be used
   – a catch that uses (…) for its parameters acts like an else (catches any throw)
       • so it should only be listed at the end of all catch blocks for the given try block
       • if there is no catch to match the throw, then the exception is propagated to the
         next level or to the function’s caller
       • the process terminates if an exception is propagated to main and there is no
         handler there
• Continuation after a handler always returns to the first statement
  following the last handler in the sequence
   – although a handler could re-invoke itself
• There are only user-defined exceptions
• C++’s exception handling is much simpler than Ada or PL/I
#include <iostream.h>                  C++ Example
void main() {
     int new_grade, index, limit1, limit2, freq[10] = {0,0,0,0,0,0,0,0,0,0};
     short int eof_condition;
     try {
         while(1) {
             if(!cin >> new_grade) throw eof_condition;
             index = new_grade / 10;
            {try {
                 if (index < 0 || index > 9) throw(new_grade);
      catch(int grade) {
             if(grade = = 100) freq[9]++; else cout << “Error – new grade out of range”;
         } // catch
       } // inner try
    } // while
 } // outer try
 catch(short int) {
      … output for the program goes here
   } // catch
} // main
• In Java, exceptions are objects
   – there are already a number of built-in exception classes (all
     descended from the built-in class Throwable), as well as the
     facility to define your own exception classes
      • Throwable has two built-in subclasses:
          – Error - errors thrown by the Java interpreter such as out of heap memory
          – Exception - errors thrown by the user program
              » examples include NullPointerException, EOFException,
                 FileNotFoundException, IOException, ArithmeticException,
                 NegativeArraySizeException, and ArrayIndexOutOfBoundsException
   – as in C++, the programmer can raise an exception using the
     throw clause
      • throw new foo (“Bad news”);
   – and like C++, there are Try and Catch clauses
      • try { … } catch (Exception foo) { … }
   – all Catch’s must have a parameter which must be of a type that
     is a descendent of the class Throwable
 Throwing, Catching, Continuation
• Built-in exceptions will be thrown automatically if the
  exception arises
• User-defined exceptions are thrown explicitly through a
  throw statement (as in C++)
   – built-in exceptions can also be thrown explicitly
• The catch block that catches an exception is based on
  the type of exception, not on a parameter type
   – exceptions can be handled in the given block or are
     propagated if the method explicitly states throws
     ExceptionType in its header, in which case the exception is
     propagated to the caller
      • this can continue until the main program is reached in which case, if
        not handled, the program terminates
               Finally, Continuation
• Aside from the throw and catch clauses, Java allows a finally
• The finally clause can be a “clean up” set of code for the object
   – that is, if any exception arises, there might need to be some routine that
     makes sure the object can continue
• The finally clause is always executed prior to continuation
  whether an exception arises or not and regardless of the type of
• Continuation occurs with the statement after the Try construct
   – if there is none, then continuation occurs with the caller of the method and
     so forth up the run-time stack
   – ultimately, if no method is found, continuation occurs with the original
     application program or termination
• A return statement in the handler terminates the method entirely
   – an example similar to the C++ example is given in the book on pages 639-
• In PL/I, exception handling was complicated because
   – continuation could go anywhere (through GO TO statements)
   – dynamic binding of handlers to code reduced readability
• In Ada, there was an attempt to simplify exceptions
   – but because of the difference between exceptions being raised in a
     block, procedure, package or loop, continuation was still complex
• In both languages, defining your own exceptions was possible
• In C++, exception handling was simplified as much as possible
   – possibly to the point of making it too weak
   – since there are no user-defined exceptions, only programmer-
     specified throw statements
• Java seems to have the best (so far) including the finally clause,
  and capabilities for user-defined as well as system-defined
   – C# also has exception handling that are similar to Java except that there is
     no throws clause for method headers
                    Event Handling
• Event handling can be thought of as a form of exception
   – typically, exception handling is meant to convey that
     something unexpected arose, handle it
      • and to prevent run-time error situations from causing program
   – but recall the C++ and Ada programs from earlier, one
     exception was simply the exception that caused termination of
     the loop
• We can treat other types of events in the same manner
   – an event is simply the notification that something specific
     occurred, using with respect to input (mouse motion or button,
     key entry)
   – an event handler is the code defined to handle the event
      • both Java and JavaScript have event handling capabilities although the
        mechanisms differ from exception handling in Java, they are similarly