Exceptions: Difference between revisions
→try-catch: langtag |
|||
Line 512: | Line 512: | ||
===Defining exceptions=== |
===Defining exceptions=== |
||
Exceptions can only be declared at the "top-level" of a module or interface. Arguments are optional. |
Exceptions can only be declared at the "top-level" of a module or interface. Arguments are optional. |
||
<lang modula3>EXCEPTION EndOfFile; |
|||
<pre> |
|||
EXCEPTION |
EXCEPTION Error(TEXT);</lang> |
||
EXCEPTION Error(TEXT); |
|||
</pre> |
|||
===Throw exceptions=== |
===Throw exceptions=== |
||
Exceptions can be bound to procedures using RAISES: |
Exceptions can be bound to procedures using RAISES: |
||
⚫ | |||
<pre> |
|||
⚫ | |||
... |
... |
||
RAISE EndOfFile; |
RAISE EndOfFile; |
||
... |
... |
||
</ |
</lang> |
||
===Catching exceptions=== |
===Catching exceptions=== |
||
<lang modula3>TRY |
|||
<pre> |
|||
TRY |
|||
Foo(); |
Foo(); |
||
EXCEPT |
EXCEPT |
||
| EndOfFile => HandleFoo(); |
| EndOfFile => HandleFoo(); |
||
END; |
END;</lang> |
||
</pre> |
|||
Modula-3 also has a FINALLY keyword: |
Modula-3 also has a FINALLY keyword: |
||
<lang modula3>TRY |
|||
<pre> |
|||
TRY |
|||
Foo(); |
Foo(); |
||
FINALLY |
FINALLY |
||
CleanupFoo(); (* always executed *) |
CleanupFoo(); (* always executed *) |
||
END; |
END; |
||
</ |
</lang> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
Revision as of 21:17, 7 March 2009
You are encouraged to solve this task according to the task description, using any language you may know.
These are examples of control structures. You may also be interested in:
This task is to give an example of an exception handling routine and to "throw" a new exception.
Ada
Define an exception
<lang ada> Foo_Error : exception; </lang>
Raise an exception
<lang ada> procedure Foo is begin
raise Foo_Error;
end Foo; </lang> Re-raising once caught exception: <lang ada>
...
exception
when Foo_Error => if ... then -- Alas, cannot handle it here, raise; -- continue propagation of end if;
</lang>
Handle an exception
<lang ada> procedure Call_Foo is begin
Foo;
exception
when Foo_Error => ... -- do something when others => ... -- this catches all other exceptions
end Call_Foo; </lang>
Ada.Exceptions
The standard package Ada.Exceptions provides a possibility to attach messages to exceptions, to get exception occurrence information and textual description of exceptions. The following example illustrates basic functionality of: <lang ada> with Ada.Exceptions; use Ada.Exceptions; with Ada.Text_IO; use Ada.Text_IO;
procedure Main is begin
... Raise_Exception (Foo_Error'Identity, "This is the exception message"); ..
exception
when Error : others => Put_Line ("Something is wrong here" & Exception_Information (Error));
end Main; </lang>
ALGOL 68
Define an exception
# a user defined object # MODE OBJECTFOO = STRUCT ( PROC (REF OBJECTFOO)BOOL foo event mended, ... ); PROC on foo event = (REF OBJECTFOO foo, PROC (REF OBJECTFOO)BOOL foo event)VOID: ( foo event mended OF foo := foo event );
Raise an exception
OBJECTFOO foo proxy := foo base; # event routines are specific to an foo # on foo event(foo proxy, raise foo event); WHILE TRUE DO # now raise example foo event # IF NOT (foo event mended OF foo proxy)(foo proxy) THEN undefined # trace back # FI OD;
Re-raising once caught exception:
... except foo event: IF ... THEN # Alas, cannot handle it here continue propagation of # IF NOT (foo event mended OF foo base)(foo base) THEN undefined # trace back # FI FI
Handle an exception
PROC raise foo event(REF OBJECTFOO foo)BOOL: IF mend foo(foo) THEN TRUE # continue # ELSE except foo event FALSE # OR fall back to default event routine # FI
Standard Preclude "on event" routines
ALGOL 68 uses event routines extensively in the "standard transput" (stdio) to manage the various events that arise when data is read (or written) to a file or external device. The built in "on event" routines are:
- on char error - if the character transput (input or output) in cannot be converted to the standard character set.
- on format error - if the format specified is incompatible to the data being transput (input or output)
- on line end - if an end of line was read while the program was "transputting" data
- on logical file end - if the end of data was encounted during transput
- on page end - if the end of a page was encounted during transput
- on physical file end - if the end of physical media was encounted during transput
- on value error - if the data transput was incompatibly with the variable being transput, eg a letter when a digit was expected.
All of the above allow the programmer to define a user created event routine when a particular event happens to a particular FILE. When such an event routine is called, then the routine can use any of the standard preclude routine to reposition the FILE and rectify the detected event, eg:
- space or back space
- new line, new page, set or reset.
For example: these may notify the operator to mount a new tape (in the case of physical file end).
The handler is permitted to return TRUE depending on whether the event has been handled and the program can can continue. And FALSE is when event remains unhandled, and the standard preclude event routine should be used. The handler is also permitted to exit to a label (without returning anything) if the user defined event routine determines that processing is complete.
AppleScript
try
try set num to 1 / 0 --do something that might throw an error end try
try-on error
try set num to 1 / 0 --do something that might throw an error on error errMess number errNum --errMess and number errNum are optional display alert "Error # " & errNum & return & errMess end try
error
error "Error message." number 2000
C
The setjmp()/longjmp() functions in the C standard library header <setjmp.h> are typically used for exception handling.
try-catch
<lang c> #include <setjmp.h>
enum { MY_EXCEPTION = 1 }; /* any non-zero number */ jmp_buf env; void foo() { longjmp(env, MY_EXCEPTION); /* throw MY_EXCEPTION */ } void call_foo() { switch (setjmp(env)) { case 0: /* try */ foo(); break; case MY_EXCEPTION: /* catch MY_EXCEPTION */ /* handle exceptions of type MY_EXCEPTION */ break; default: /* handle any type of exception not handled by above catches */ } }</lang>
C++
C++ has no finally construct. Instead you can do this in the destructor of an object on the stack, which will be called if an exception is thrown.
The exception can be of any type, this includes int's, other primitives, as well as objects.
Defining exceptions
<lang cpp> struct MyException {
// data with info about exception
}; </lang>
There's also a class std::exception which you can, but are not required to derive your exception class from. The advantage of doing so is that you can catch unknown exceptions and still get some meaningful information out. There are also more specific classes like std::runtime_error which derive from std::exception.
<lang cpp>
- include <exception>
struct MyException: std::exception {
char const* what() const throw() { return "description"; }
} </lang>
Note that in principle you can throw any copyable type as exception, including built-in types.
Throw exceptions
<lang cpp> // this function can throw any type of exception void foo() {
throw MyException();
}
// this function can only throw the types of exceptions that are listed void foo2() throw(MyException) {
throw MyException();
}
// this function turns any exceptions other than MyException into std::bad_exception void foo3() throw(MyException, std::bad_exception) {
throw MyException();
} </lang>
Catching exceptions
<lang cpp>
try { foo(); } catch (MyException &exc) { // handle exceptions of type MyException and derived } catch (std::exception &exc) { // handle exceptions derived from std::exception, which were not handled by above catches // e.g. std::cerr << exc.what() << std::endl; } catch (...) { // handle any type of exception not handled by above catches }
</lang>
C#
Defining exceptions
public class MyException : Exception { // data with info about exception };
Throw exceptions
void foo() { throw MyException(); }
Catching exceptions
try { foo(); } catch (MyException e) { // handle exceptions of type MyException and derived } catch { // handle any type of exception not handled by above catches }
ColdFusion
Catch Exceptions
inside <cfscript>:
try { foo(); } catch (Any e) { // handle exception e }
otherwise:
<cftry> <cfcatch type="Database|..."> </cfcatch> </cftry>
D
Throw Exceptions
<lang d>void test() {
throw new Exception("Sample Exception");
}</lang>
Catch Exceptions
<lang d>void test2() {
try test(); catch (Exception ex) { writefln(ex); throw ex; /* rethrow */ }
}</lang>
In debug mode, stack traces can be generated via an external package, but the standard library does not support it by default.
Ways to implement finally
<lang d>void test3() {
try test2(); finally writefln("test3 finally");
}</lang> Or also with scope guards! <lang d>void test4() {
scope(exit) writefln("Test4 done"); scope(failure) writefln("Test4 exited by exception"); scope(success) writefln("Test4 exited by return or function end"); test2();
}</lang>
Factor
Throw Exceptions
"Install Linux, Problem Solved" throw
TUPLE: velociraptor ; \ velociraptor new throw
Or a shorthand for this:
ERROR: velociraptor ; velociraptor
Catch Exceptions
! Preferred exception handling : try-foo [ foo ] [ foo-failed ] recover ;
: try-bar [ bar ] [ bar-errored ] [ bar-always ] cleanup ;
! Used rarely [ "Fail" throw ] try ! throws a "Fail" [ "Fail" throw ] catch ! returns "Fail" [ "Hi" print ] catch ! returns f (looks the same as throwing f; don't throw f) [ f throw ] catch ! returns f, bad! use recover or cleanup instead
Forth
Forth's exception mechanism is, like most things in Forth, very simple but powerful. CATCH captures the data and return stack pointers, then executes an execution token. THROW conditionally throws a value up to the most recent CATCH, restoring the stack pointers.
Throw Exceptions
: f ( -- ) 1 throw ." f " ; \ will throw a "1" : g ( -- ) 0 throw ." g " ; \ does not throw
Catch Exceptions
: report ( n -- ) ?dup if ." caught " . else ." no throw" then ; : test ( -- ) ['] f catch report ['] g catch report ;
test example. (Output shown in bold)
cr test caught 1 g no throw ok
Note that CATCH only restores the stack pointers, not the stack values, so any values that were changed during the execution of the token will have undefined values. In practice, this means writing code to clean up the stack, like this:
10 ['] myfun catch if drop then
Haskell
Exceptions can be implemented using monads; no special syntax is necessary.[1] In GHC, specialized functionality for exceptions are provided by the Control.Exception module.
Defining exceptions
The type "Exception", which contains pre-defined exceptions, cannot be extended. You can however use "dynamic exceptions", which can be of any type that is of "Typeable" class.
Throw exceptions
In the context of the IO monad, use "throwIO" to throw exceptions; the expression will return any type:
do {- ... -} throwIO SomeException
In purely functional context, use "throw" to throw exceptions; the expression will match any type:
if condition then 3 else throw SomeException
To throw a user-defined exception, use "throwDyn":
if condition then 3 else throwDyn myException
Catching exceptions
The "catch" function performs the whole try-catch stuff. It is usually used in infix style: pattern-matches on the exception type and argument:
do {- do IO computations here -} `catch` \ex -> do {- handle exception "ex" here -}
Note: Control.Exception's "catch" is different than Prelude's "catch".
To catch a user-defined exception, use "catchDyn":
do {- do IO computations here -} `catchDyn` \ex -> do {- handle exception "ex" here -}
J
Program u :: v executes u and provides its result as output unless an error occurs. In case of error, the result of v is provided instead.
An exception in an explicit definition can be detected with try. and catcht. and can be thrown with throw. as seen below.
pickyPicky =: verb define if. y-:'bad argument' do. throw. else. 'thanks!' end. ) tryThis =: verb define try. pickyPicky y catcht. 'Uh oh!' end. ) tryThis 'bad argument' Uh oh!
Java
An exception needs to extend the Exception type.
Defining exceptions
//Checked exception public class MyException extends Exception { //Put specific info in here }
//Unchecked exception public class MyRuntimeException extends RuntimeException {}
Throw exceptions
public void fooChecked() throws MyException { throw new MyException(); }
public void fooUnchecked() { throw new MyRuntimeException(); }
Catching exceptions
try { fooChecked(); } catch(MyException exc) { //Catch only your specified type of exception } catch(Exception exc) { //Catch any non-system error exception } catch(Throwable exc) { //Catch everything including system errors (not recommended) } finally { //This code is always executed after exiting the try block }
JavaScript
Throwing exceptions
function doStuff() { throw new Error('Not implemented!'); }
Catching exceptions
try { element.attachEvent('onclick', doStuff); } catch(e if e instanceof TypeError) { element.addEventListener('click', doStuff, false); } finally { eventSetup = true; }
Logo
to div.checked :a :b if :b = 0 [(throw "divzero 0)] output :a / :b end to div.safely :a :b output catch "divzero [div.checked :a :b] end
There are also some predefined exceptions:
- throw "toplevel returns to the interactive prompt if uncaught (like control-C)
- (throw "error [message]) prints a message like a primitive, bypassing normal catch output
- throw "system immediately exits Logo to the shell
- catch "error will catch any thrown error instead of printing an error message
Make
In make, an exception is caused when a rule returns a non-zero status i.e the below will fail as false returns 1, (thus raising exception)
fail.mk
all: false
Using -@ to ignore the exception.
catch.mk
all: -@make -f fail.mk
Using explicit exit 0 to ignore the exception.
catch.mk
all: make -f fail.mk; exit 0
Modula-3
Defining exceptions
Exceptions can only be declared at the "top-level" of a module or interface. Arguments are optional. <lang modula3>EXCEPTION EndOfFile; EXCEPTION Error(TEXT);</lang>
Throw exceptions
Exceptions can be bound to procedures using RAISES: <lang modula3>PROCEDURE Foo() RAISES { EndOfFile } =
... RAISE EndOfFile; ...
</lang>
Catching exceptions
<lang modula3>TRY
Foo();
EXCEPT | EndOfFile => HandleFoo(); END;</lang>
Modula-3 also has a FINALLY keyword: <lang modula3>TRY
Foo();
FINALLY
CleanupFoo(); (* always executed *)
END; </lang>
OCaml
Defining exceptions
Like constructors, exceptions may or may not have an argument:
exception My_Exception;; exception Another_Exception of string;;
Throw exceptions
Throw exceptions with the "raise" function; the expression will match any type:
let foo x = match x with 1 -> raise My_Exception | 2 -> raise (Another_Exception "hi mom") | _ -> 5 ;;
Catching exceptions
The "with" syntax pattern-matches on the exception type and argument:
try string_of_int (foo 2) with My_Exception -> "got my exception" | Another_Exception s -> s | _ -> "unknown exception"
Perl
# throw an exception die "Danger, danger, Will Robinson!"; # catch an exception and show it eval { die "this could go wrong mightily"; }; print $@ if $@; # rethrow die $@;
See http://perldoc.perl.org/perlvar.html#%24EVAL_ERROR for the meaning of the special variable $@. See http://search.cpan.org/dist/Error for an advanced, object based exception handling.
PHP
Exceptions were not available prior to PHP 5.0
Define exceptions
class MyException extends Exception { // Custom exception attributes & methods }
Throwing exceptions
function throwsException() { throw new Exception('Exception message'); }
Catching Exceptions
try { throwsException(); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); }
Pop11
Throwing exceptions
define throw_exception(); throw([my_exception my_data]); enddefine;
Catching exceptions
define main(); vars cargo; define catcher(); ;;; print exception data cargo => enddefine; catch(throw_exception, catcher, [my_exception ?cargo]); enddefine; main();
Python
Defining an exception
<lang python> import exceptions
class SillyError(exceptions.Exception): def __init__(self,args=None): self.args=args</lang>
Note: In most cases new exceptions are defined simply using the pass statement. For example:
<lang python> class MyInvalidArgument(ValueError):
pass
</lang>
This example makes "MyInvalidArgument" an type of ValueError (one of the built-in exceptions). It's simply declared as a subclass of the existing exception and no over-riding is necessary. (An except clause for ValueError would catch MyInvalidArgument exceptions ... but one's code could insert a more specific exception handler for the more specific type of exception).
Throwing an exception
Creating an exception using the default constructor of an exception class: <lang python>def spam():
raise SillyError # equivalent to raise SillyError()</lang>
Passing an argument to the constructor of an exception class: <lang python>def spam():
raise SillyError, 'egg' # equivalent to raise SillyError('egg')</lang>
The above syntax is removed in Python 3.0; but the following syntax works in Python 2.x and 3.x, so should be preferred.
<lang python>def spam():
raise SillyError('egg')</lang>
Handling an exception
try-except-finally-else
<lang python>try:
foo()
except SillyError, se:
print se.args bar()
finally:
baz()
else:
# no exception occurred quux()</lang>
Before Python 2.5 it was not possible to use finally and except together. (It was necessary to nest a separate try...except block inside of your try...finally block).
Note: Python3 will change the syntax of except slightly, but in a way that is not backwards compatible. In Python 2.x and earlier the except statement could list a single exception or a tuple/list of exceptions and optionally a name to which the exception object will be bound. In the old versions the exception's name followed a comma (as in the foregoing example). In Python3 the syntax will become: except Exception1 [,Exception2 ...] as ExceptionName <lang python>try:
foo()
except SillyError as se:
print(se.args) bar()
finally:
baz()
else:
# no exception occurred quux()</lang>
Raven
42 as custom_error define foo custom_error throw try foo catch custom_error = if 'oops' print
Ruby
Defining an exception
<lang ruby>class SillyError < Exception
def initialize(args = nil) @args = args end
end</lang>
Note: Often new exceptions are defined simply with no body. For example:
<lang ruby>class MyInvalidArgument < ArgumentError end</lang>
This example makes "MyInvalidArgument" an type of ArgumentError (one of the built-in exceptions). It's simply declared as a subclass of the existing exception and no over-riding is necessary. (A rescue clause for ArgumentError would catch MyInvalidArgument exceptions ... but one's code could insert a more specific exception handler for the more specific type of exception).
Throwing an exception
<lang ruby>def spam
raise SillyError, 'egg'
end</lang>
Handling an exception
rescue/else/ensure
<lang ruby>begin
foo
rescue SillyError, se
print se.args bar()
else
# no exception occurred quux
ensure
baz
end</lang>
The "rescue" clause is like the "catch" clause in other languages. The "ensure" clause is like the "finally" clause in other languages.
Catch/Throw
Ruby has a separate exception-like system that is meant to be used to exit out of deep executions that are not errors.
<lang python>def foo
throw :done
end
catch :done do
foo
end</lang>
You can only "throw" and "catch" symbols. Like exceptions, the throw can be made from a function defined elsewhere from the catch block.
Standard ML
Define Exceptions
exception MyException; exception MyDataException of int; (* can be any first-class type, not just int *)
Throw Exceptions
fun f() = raise MyException; fun g() = raise MyDataException 22;
Catch Exceptions
val x = f() handle MyException => 22; val y = f() handle MyDataException x => x;
V
throwing exceptions
[myproc ['new error' 1 2 3] throw 'should not come here' puts ].
catching them
[myproc] [puts] catch =[new error 1 2 3]
Visual Basic .NET
Defining exceptions
Class MyException Inherits Exception 'data with info about exception End Class
Throw exceptions
Sub foo() Throw New MyException End Sub
Catching exceptions
Sub bar() Try foo() Catch e As MyException When e.Data.Contains("Foo") ' handle exceptions of type MyException when the exception contains specific data Catch e As MyException ' handle exceptions of type MyException and derived exceptions Catch e As Exception ' handle any type of exception not handled by above catches Finally 'code here occurs whether or not there was an exception End Try End Sub