Exception handling syntax is the set of keywords and/or structures provided by a computer programming language to allow exception handling, which separates the handling of errors that arise during a program's operation from its ordinary processes. Syntax for exception handling varies between programming languages, partly to cover semantic differences but largely to fit into each language's overall syntactic structure. Some languages do not call the relevant concept "exception handling"; others may not have direct facilities for it, but can still provide means to implement it.
Most commonly, error handling uses a try { /* ... */ } catch (/* ... */) { /* ... */ } finally { /* ... */ } chain of blocks, and errors are created via a throw statement, but there is significant variation in naming and syntax.
Catalogue of exception handling syntaxes
Ada
Exception declarations Some_Error : exception;
Raising exceptions raise Some_Error;
raise Some_Error with "Out of memory"; -- specific diagnostic message
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;
Assembly language
Most assembly languages have a macro instruction or an interrupt address available for the particular system to intercept events such as illegal opcodes, overflow, and divide by zero. IBM and UNIVAC mainframes have the STXIT macro. Digital Equipment Corporation RT11 systems have trap vectors. Windows has specific module calls to trap program errors.
ATS
exception MyException of (string, int) (* exceptions can carry a value *)
implement main0 (): void = try $raise MyException("not enough food", 2) with | ~MyException(s, i) => begin $extfcall(void, "fprintf", stderr_ref, "%s: %d", s, i); fileref_close(stderr_ref); end
Bash
#!/usr/bin/env bash #set -e provides another error mechanism print_error() { echo "there was an error" } trap print_error exit #list signals to trap tempfile=`mktemp` trap "rm $tempfile" exit ./other.sh || echo warning: other failed echo oops) echo never printed
One can set a trap for multiple errors, responding to any signal with syntax like:
BASIC
An On Error goto/gosub structure is used in BASIC and is quite different from modern exception handling; in BASIC there is only one global handler whereas in modern exception handling, exception handlers are stacked.
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 ' RESUME may be used instead which returns control to original position.
C
C does not provide direct support to exception handling: it is the programmer's responsibility to prevent errors in the first place and test return values from the functions.
In any case, a possible way to implement exception handling in standard C is to use / functions: #include <setjmp.h> #include <stdio.h> #include <stdlib.h>
enum Exception { NoExceptionThrown = 0, OutOfBoundsException = 1, ArithmeticException = 2, // ... } GLOBAL_EXCEPTION_STATE;
jmp_buf state;
int main(int argc, char* argv[]) { // try if (!setjmp(state)) { // code that manipulates 'GLOBAL_EXCEPTION_STATE' if (GLOBAL_EXCEPTION_STATE != NoExceptionThrown) { longjmp(state, 0); // go to exception catching...
} else { switch (GLOBAL_EXCEPTION_STATE) { // catch (OutOfBoundsException) case OutOfBoundsException: printf("OutOfBoundsException caught"); break; // catch (ArithmeticException) case ArithmeticException: printf("ArithmeticException caught"); break; // additional catch cases... default: // catch (...) printf("Unknown exception caught");
return EXIT_SUCCESS; }
Microsoft-specific
Two types exist: Structured Exception Handling (SEH) Vectored Exception Handling (VEH, introduced in Windows XP) Example of SEH in C programming language: int filterExpression(EXCEPTION_POINTERS* ep) { ep->ContextRecord->Eip += 8; // divide instruction may be encoded from 2 to 8 bytes return EXCEPTION_CONTINUE_EXECUTION; }
int main(int argc, char* argv[]) { static int zero = 0; __try { zero = 1 / zero; asm { nop nop nop nop nop nop nop
printf("Past the exception.\n"); } __except (filterExpression(GetExceptionInformation())) { printf("Handler called.\n");
return 0; }
C#
A try block must have at least one catch or finally clause and at most one finally clause. namespace Wikipedia.Examples;
using System; using System.Web;
public class Example { static void Main(string[] argsg)
try
// Code that could throw an exception.
catch (HttpException ex)
// Handles a HttpException (System.Web.HttpException). // The exception object is stored in "ex".
catch (Exception)
// Handles any CLR exception that is not a HttpException. // Since the exception has not been given an identifier, it cannot be referenced.
catch
// Handles anything that might be thrown, including non-CLR exceptions // (such as native C++ exceptions)
finally
// Always run when leaving the try block (including catch clauses), regardless of whether any exceptions were thrown or whether they were handled. // Often used to clean up and close resources such a file handles. // May not be run when Environment.FailFast() is called and in other system-wide exceptional conditions (e.g. power loss), or when the process crashes due to an exception in another thread.
C++
import std;
using std::exception; using std::runtime_error;
int main(int argc, char* argv[]) { try { // do something (might throw an exception) mightThrow(); } catch (const runtime_error& e) { // handle a runtime_error e } catch (const exception& e) { // catches all exceptions as e } catch (...) { // catches all thrown types (including primitives or objects that do not extend exception), not previously caught by a catch block before
In C++, a resource acquisition is initialization technique can be used to clean up resources in exceptional situations. C++ intentionally does not support .Bjarne Stroustrup's FAQ The outer braces for the method are optional.
ColdFusion Markup Language (CFML)
Script syntax <cfscript> try { // throw CF9+ throw(type="TypeOfException", message="Oops", detail="xyz"); // alternate throw syntax: throw "Oops"; // this equivalent to the "message" value in the above example } catch (any e) { writeOutput("Error: " & e.message); rethrow; // CF9+ } finally { // CF9+ writeOutput("I run even if no error"); } </cfscript>
Adobe ColdFusion documentation
Tag syntax <cftry> code that may cause an exception <cfcatch ...> <cftry> First level of exception handling code <cfcatch ...> Second level of exception handling code </cfcatch> <cffinally> final code </cffinally> </cftry> </cfcatch> </cftry> Adobe ColdFusion documentation
Railo-Lucee specific syntax
Added to the standard syntax above, CFML dialects of Railo and Lucee allow a retry statement.# JBoss Community issue tracker ticket for adding retry
This statement returns processing to the start of the prior try block.
CFScript example: try { // code which could result in an exception } catch (any e){ retry; }
Tag-syntax example: <cftry>
<!--- code which could result in an exception --->
<cfcatch> <cfretry> </cfcatch> </cftry>
D
import std.stdio;
int main(string[] args) { try { // do something that might throw an exception } catch (FileException e) { // handle exceptions of type FileException } catch (Object o) { // handle any other exceptions writefln("Unhandled exception: ", o); return 1;
return 0; } In D, a clause or the resource acquisition is initialization technique can be used to clean up resources in exceptional situations.
Delphi
Exception declarations type ECustom = class(Exception) // Exceptions are children of the class Exception. private FCustomData: SomeType; // Exceptions may have custom extensions. public constructor CreateCustom(Data: SomeType); // Needs an implementation property CustomData: SomeType read FCustomData; end;
Raising exceptions raise Exception.Create('Message');
raise Exception.CreateFmt('Message with values: %d, %d',[value1, value2]); // See SysUtils.Format() for parameters.
raise ECustom.CreateCustom(X);
Exception handling and propagationBorland, Delphi Version 7.0, Online help try // For finally. try // For except. ... // Code that may raise an exception. except on C:ECustom do begin ... // Handle ECustom. ... if Predicate(C.CustomData) then ... end; on S:ESomeOtherException do begin // Propagate as an other exception. raise EYetAnotherException.Create(S.Message); end; on E:Exception do begin ... // Handle other exceptions. raise; // Propagate. end; end; finally // Code to execute whether or not an exception is raised (e.g., clean-up code). end;
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
F#
In addition to the OCaml-based try...with, F# also has the separate try...finally construct, which has the same behavior as a try block with a finally clause in other .NET languages.
For comparison, this is a translation of the C# sample above. try try () (* Code that could throw an exception. *) with | :? System.Net.WebException as ex -> () (* Handles a WebException. The exception object is stored in "ex". *) | :? exn -> () (* Handles any CLR exception. Since the exception has not been given an identifier, it cannot be referenced. *) | _ -> () (* Handles anything that might be thrown, including non-CLR exceptions. *) finally () (* Always run when leaving the try block, regardless of whether any exceptions were thrown or whether they were handled. Often used to clean up and close resources such a file handles. May not be run when Environment.FailFast() is called and in other system-wide exceptional conditions (e.g. power loss), or when the process crashes due to an exception in another thread. *)
For comparison, this is translation of the OCaml sample below. exception MyException of string * int (* exceptions can carry a value *) let _ = try raise (MyException ("not enough food", 2)); printfn "Not reached" with | MyException (s, i) -> printf "MyException: %s, %d\n" s i | e -> (* catch all exceptions *) eprintf "Unexpected exception : %O" e; eprintf "%O" e.StackTrace
Haskell
Haskell does not have special syntax for exceptions. Instead, a ///. interface is provided by functions.
import Prelude hiding(catch) import Control.Exception instance Exception Int instance Exception Double main = do catch (catch (throw (42::Int)) (\e-> print (0,e::Double))) (\e-> print (1,e::Int))
prints
(1,42)
in analogy with this C++
import std;
int main(int argc, char* argv[]) { try { throw static_cast<int>(42); } catch (double d) { std::println("(0,{})", d); } catch (int i) { std::println("(1,{})", i);
Another example is
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 type may be sufficient, and is an instance of Haskell's class by default. More complex error propagation can be achieved using the or monads, for which similar functionality (using ) is supported.
Java