Exception handling syntax

From Wikipedia, the free encyclopedia

Jump to: navigation, search

Exception handling syntax varies between programming languages to accommodate their overall syntax. Some languages don't call the concept exception handling or they may not have direct facilities for it, but they can still provide means for implementing it.

Contents

[edit] Catalogue of exception handling syntaxes

[edit] Ada

[edit] Exception declarations

Some_Error : exception;

[edit] Raising exceptions

raise Some_Error;
 
raise Some_Error with "Out of memory"; -- specific diagnostic message

[edit] Exception handling and propagation

with Ada.Exceptions, Ada.Text_IO;
 
procedure Foo is
  Some_Error : exception;
begin
  Do_Something_Interesting;
exception -- Start of exception handlers
  when Constraint_Error =>
    ... -- Handle constraint error
  when Storage_Error =>
    -- Propagate Storage_Error as a different exception with a useful message
    raise Some_Error with "Out of memory";
  when Error : others => 
    -- Handle all others
    Ada.Text_IO.Put("Exception: ");
    Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Name(Error));
    Ada.Text_IO.Put_Line(Ada.Exceptions.Exception_Message(Error));
end Foo;

[edit] BASIC

ON ERROR GOTO handler
OPEN "Somefile.txt" FOR INPUT AS #1
CLOSE #1
PRINT "File opened successfully"
END
 
handler:
PRINT "File does not exist"
END

[edit] C

The most common way to implement exception handling in standard C is to use setjmp/longjmp functions:

#include <setjmp.h>
#include <stdio.h>
enum { SOME_EXCEPTION = 1 };
jmp_buf state;
int main()
{
  int exception;
  if((exception = setjmp(state)) == 0)  // try
  {
    if(/* something happened */)
      longjmp(state, SOME_EXCEPTION);   // throw SOME_EXCEPTION
  } 
  else switch(exception)
  {             
    case SOME_EXCEPTION:                  // catch SOME_EXCEPTION
      puts("SOME_EXCEPTION caught");
      break;
    default:                              // catch ...
      puts("Some strange exception");
  }
  return 0;
}

Some operating systems also have similar features, for example Microsoft Windows has "Structured Exception Handling" (SEH):

int filterExpression (EXCEPTION_POINTERS* ep) {
   ++ep->ContextRecord->Eip;
   return EXCEPTION_CONTINUE_EXECUTION;
}
int main() {
   static int zero;
   __try {
       zero = 1/zero;
       printf ("Past the exception.\n");
   } __except (filterExpression (GetExceptionInformation())) {
       printf ("Handler called.\n");
   }
   return 0;
}

[edit] C#

public static void Main()
{
   try
   {
      // Code that could throw an exception
   }
   catch(System.Net.WebException exp)
   {
      // Process a WebException
   }
   catch(System.Exception)
   {
      // Process a System level CLR exception, that is not a System.Net.WebException,
      // since the exception has not been given an identifier it cannot be referenced
   }
   catch
   {
      // Process a non-CLR exception
   }
   finally
   {
      // (optional) code that will *always* execute
   }
}

[edit] C++

#include <exception>
int main() {
   try {
       // do something (might throw an exception)
   }
   catch (const std::exception& e) {
        // handle exception e
   }
   catch (...) {
        // unknown exception, should not happen
   }
}

In C++, a resource acquisition is initialization technique can be used to clean up resources in exceptional situations.

[edit] D

import std.stdio; // for writefln()
int main() {
  try {
      // do something that might throw an exception
  }
  catch (FooException e) {
       // handle exceptions of type FooException
  }
  catch (Object o) {
       // handle any other exceptions
       writefln("Unhandled exception: ", o);
       return 1;
  }
  return 0;
}

In D, a finally clause or the resource acquisition is initialization technique can be used to clean up resources in exceptional situations.

[edit] Delphi

try
  try
    // Code which may raise an exception
  except
    on E:Exception do
    // Code to call when an exception is raised
  end;
finally
  // Code which will be executed whether or not an exception is raised (e.g. clean-up code)
end;

[edit] Erlang

try
  % some dangerous code
catch
  throw:{someError, X} -> ok;    % handle an exception
  error:X -> ok;                 % handle another exception
  _:_ -> ok                      % handle all exceptions
after
  % clean up
end

[edit] Fault Tolerant Shell

try for 30 minutes
     cd /tmp
     rm -f data
     forany host in xxx yyy zzz
           wget http://${host}/fresh.data -O data
     end
end

[edit] Haskell

Haskell does not have special syntax for exception handling, because throwing an exception can be realized generically as a monad. However, the function catch can be used within the IO monad:

do {
  -- Statements in which errors might be thrown
} `catch` \ex -> do {
  -- Statements that execute in the event of an exception, with 'ex' bound to the exception
}

In purely functional code, if only one error condition exists, the Maybe monad may be sufficient, and is an instance of Haskell's Monad class by default. More complex error propagation can be achieved using the Error or ErrorT monads, for which similar syntax (using `catch`) is supported.

[edit] Java

try {
   // Normal execution path
} catch (ExampleException ee) {
   //  deal with the ExampleException
} finally {
   // This optional section is executed upon termination of any of the try or catch blocks above
}

[edit] JavaScript

try {
  // Statements in which exceptions might be thrown
} catch(error) {
  // Statements that execute in the event of an exception
} finally {
  // Statements that execute afterward either way
}

[edit] Common Lisp

(ignore-errors (/ 1 0))
 
(handler-case
    (progn
      (print "enter an expression")
      (eval (read)))
  (error (e) (print e)))

[edit] Objective-C

[edit] Exception declarations

NSException *exception = [NSException exceptionWithName:@"myException"
                           reason:@"whatever"  userInfo:nil];

[edit] Raising exceptions

@throw exception;

[edit] Exception handling and propagation

@try {
    ...
}
@catch (SomeException *se) {
    // Handle a specific exception type.
    ...
}
@catch (NSException *ne) {
    // Handle general exceptions.
    ...
 
    // Propagate the exception so that it's handled at a higher level.
    @throw;
}
@catch (id ue) {
    // Catch all thrown objects.
    ...
}
@finally {
    // Perform cleanup, whether an exception occurred or not.
    ...
}

[edit] OCaml

exception MyException of string * int (* exceptions can carry a value *)
let _ =
  try
    raise (MyException ("not enough food", 2));
    print_endline "Not reached"
  with
  | MyException (s, i) -> 
      Printf.printf "MyException: %s, %d\n" s i
  | e ->  (* catch all exceptions *)
     Printf.eprintf "Unexpected exception : %s" (Printexc.to_string e);
     (*If using Ocaml >= 3.11, it is possible to also print a backtrace: *)
     Printexc.print_backtrace stderr;
       (* Needs to beforehand enable backtrace recording with
           Printexc.record_backtrace true
         or by setting the environment variable OCAMLRUNPARAM="b1"*)

[edit] Perl

The Perl mechanism for exception handling uses die to throw an exception when wrapped inside an eval { ... }; block. After the eval, the special variable $@ contains the value passed from die.

eval {
  # Code that could throw an exception (using 'die')
  open(FILE, $file) || die "Could not open file: $!";
  while (<FILE>) {
    process_line($_);
  }
  close(FILE) || die "Could not close $file: $!";
};
if ($@) {
  # Handle exception here. The exception string is in $@
}

Perl 5.005 added the ability to throw objects as well as strings. This allows for better introspection and handling of types of exceptions.

eval {
  open(FILE, $file) || die MyException::File->new($!);
  while (<FILE>) {
    process_line($_);
  }
  close(FILE) || die MyException::File->new($!);
};
if ($@) {
  # The exception object is in $@
  if ($@->isa('MyException::File')) {
    # Handle file exception
  } else {
    # Generic exception handling
    # or re-throw with 'die $@'
  }
}

The __DIE__ pseudo-signal can be trapped to handle calls to die. This is not suitable for exception handling since it is global. However it can be used to convert string-based exceptions from third-party packages into objects.

local $SIG{__DIE__} = sub {
  my $err = shift;
  if ($err->isa('MyException')) {
    die $err; # re-throw
  } else {
    # Otherwise construct a MyException with $err as a string
    die MyException::Default->new($err);
  }
};

A number of modules in CPAN expand on the basic mechanism:

  • Error provides a set of exception classes and allows use of the try/throw/catch/finally syntax.
  • Exception::Class is a base class and class-maker for derived exception classes. It provides a full structured stack trace in $@->trace and $@->trace->as_string.
  • Fatal overloads previously defined functions that return true/false e.g. open, close, read, write, etc. This allows built-in functions and others to be used as if they threw exceptions.

[edit] PHP

// Exception handling is only available in PHP versions 5 and greater.
try
{
... // Code which might throw an exception
}
catch (FirstExceptionClass $exception) 
{
... // Code which handles this exception
} 
catch (SecondExceptionClass $exception) 
{
  // you get the idea what i mean ;)
}

(php5powerprogramming: ISBN 0-13-147149-X, page 77)

[edit] PowerBuilder

Exception handling is available in PowerBuilder versions 8.0 and above.

TRY
   // Normal execution path
CATCH (ExampleException ee)
   //  deal with the ExampleException
FINALLY
   // This optional section is executed upon termination of any of the try or catch blocks above
END TRY

[edit] Python

f = None
try:
   f = file("aFileName")
   f.write(could_make_error())
except IOError:
   print "Unable to open file"
except:   # catch all exceptions
   print "Unexpected error"
else:     # executed if no exceptions are raised
   print "File write completed successfully"
finally:  # clean-up actions, always executed
   if f:
      f.close()

[edit] REBOL

REBOL [
    Title: "Exception and error handling examples"
]

; TRY a block; capturing an error! and converting to object!
if error? exception: try [1 / 0][probe disarm exception]

; ATTEMPT results in the value of the block or the value none on error
print attempt [divide 1 0]

; User generated exceptions can be any datatype!
example: func ["A function to throw an exception"
][
    throw "I'm a string! exception"
]
catch [example]

; User generated exceptions can also be named,
;   and functions can include additional run time attributes 
sophisticated: func ["A function to throw a named error exception"
    [catch]
][
    throw/name make error! "I'm an error! exception" 'moniker
]
catch/name [sophisticated] 'moniker

[edit] Ruby

begin
  # Do something nifty
  raise SomeError, "This is the error message!"  # Uh-oh!
rescue SomeError
  # This is executed when a SomeError exception
  # is raised
rescue AnotherError => error
  # Here, the exception object is referenced from the
  # `error' variable
else
  # This is executed only if no exceptions were raised
ensure
  # This is always executed, exception or not
end

[edit] S-Lang

 try 
 {
    % code that might throw an exception
 }
 catch SomeError: 
 { 
    % code that handles this exception
 }
 catch SomeOtherError:
 {  
    % code that handles this exception
 }
 finally   % optional block
 {
    % This code will always get executed
 }

New exceptions may be created using the new_exception function, e.g.,

 new_exception ("MyIOError", IOError, "My I/O Error");

will create an exception called MyIOError as a subclass of IOError. Exceptions may be generated using the throw statement, which can throw arbitrary S-Lang objects.

[edit] Visual Basic .NET

Try
   ' Do Something
Catch ex As Exception When condition
   ' Handle Exception when a specific condition is true
Catch ex As Exception
   ' Handle Exception
Finally
   ' Cleanup, close connections etc
   ' NB this code is always executed regardless of if an Exception was raised or not!
End Try

[edit] Windows PowerShell

PowerShell V1.0

trap [Exception]
{
  # Statements that execute in the event of an exception
}
# Statements in which exceptions might be thrown

Or now in PowerShell V2.0-CTP3

Try {
    # Statements in which exceptions might be thrown
    }
Catch [Exception1] {
  # Statements that execute in the event of an exception, matching the exception
    }
Catch [Exception2],[Execption3etc] {
  # Statements that execute in the event of an exception, matching the exception
    }
Catch {
  # Statements that execute in the event of an exception, not handled more specifically
    }

[edit] X++

public static void Main(Args _args)
{
   try
   {
      // Code that could throw an exception
   }
   catch (Exception::Error) // Or any other exception type
   {
      // Process the error
   }
   catch
   {
      // Process any other exception type not handled previously
   }
 
   // Code here will execute as long as any exception is caught
}

[edit] See also

Personal tools