Exception handling syntax
Keywords provided by a programming language
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.
01Catalogue of exception handling syntaxes
Ada
- Exception declarations
- Raising exceptions
- Exception handling and propagation
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); endBash
#!/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 printedOne can set a trap for multiple errors, responding to any signal with syntax like:
- trap 'echo Error at line ${LINENO}' ERR
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 setjmp()/longjmp() 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 finally. 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.
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 finally clause or the resource acquisition is initialization technique can be used to clean up resources in exceptional situations.
Delphi
- Exception declarations
- Raising exceptions
- Exception handling and propagation
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 endF#
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.StackTraceHaskell
Haskell does not have special syntax for exceptions. Instead, a try/catch/finally/etc. 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 Maybe type 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 functionality (using `catch`) is supported.
Java
A try block must have at least one catch or finally clause and at most one finally clause. Java distinguishes between Exceptions (errors reasonable to catch) and Error (errors, usually more severe, unreasonable to catch), both of which are descendants of Throwable (the base class of any object which may be thrown).
package org.wikipedia.examples; import java.io.IOException; public class Example { public static void main(String[] args) { try { // Normal execution path. mayThrowIOException(); // method that can throw an IOException } catch (IOException e) { // Deal with the IOException. // IOException is a checked exception that must be caught. } catch (RuntimeException e) { // Deal with the RuntimeException. // Runtime exceptions are unchecked, and are not forced to be caught. } catch (Exception e) { // Catches anything that is an instance of Exception } catch (Throwable t) { // Catches anything that is an instance of Throwable (including both Exception and Error) } finally { // Always run when leaving the try block (including finally clauses), regardless of whether any exceptions were thrown or whether they were handled. // Cleans up and closes resources acquired in the try block. // May not be run when System.exit() is called and in other system-wide exceptional conditions (e.g. power loss). // Rarely used after try-with-resources was added to the language (see below). } } }If multiple resources are acquired, the correct way to deal with them is with nested try blocks. For this reason and others, try-with-resources was added to the language to almost entirely replace finally clauses. Resources acquired in a parentheses after the try keyword will be cleaned up automatically. Classes used in these statements must implement an interface called java.lang.AutoCloseable. This is similar to the "resource acquisition is initialization" pattern common in languages like C++, where resources are cleaned after leaving scope.
package org.wikipedia.examples; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class Example { public static void main(String[] args) { try (FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr)) { // Normal execution path. } catch (IOException e) { // Deal with exception. // Resources in the try statement are automatically closed afterwards. } finally { // A finally clause can be included, and will run after the resources in the try statements are closed. } } }JavaScript
The design of JavaScript makes loud/hard errors very uncommon. Soft/quiet errors are much more prevalent. Hard errors propagate to the nearest try statement, which must be followed by either a single catch clause, a single finally clause, or both.
try { // Statements in which exceptions might be thrown throw new Error("error"); } catch (error) { // Statements that execute in the event of an exception } finally { // Statements that execute afterward either way }If there is no try statement at all, then the webpage does not crash. Rather, an error is logged to the console and the stack is cleared. However, JavaScript has the interesting quirk of asynchronous externally-invoked entry points. Whereas, in most other languages, there is always some part of the code running at all times, JavaScript does not have to run linearly from start to end. For example, event listeners, Promises, and timers can be invoked by the browser at a later point in time and run in an isolated but shared context with the rest of the code. Observe how the code below will throw a new error every 4 seconds for an indefinite period of time or until the browser/tab/computer is closed.
setInterval(function() { throw new Error("Example of an error thrown on a 4 second interval."); }, 4000);Another interesting quirk is polymorphism: JavaScript can throw primitive values as errors.
try { throw 12345; // primitive number } catch (error) { console.log(error); // logs 12345 as a primitive number to the console }Note that the catch clause is a catch-all, which catches every type of error. There is no syntaxical ability to assign different handlers to different error types aside from experimental and presently removed Gecko extensions from many years ago. Instead, one can either propagate the error by using a throw statement inside the catch statement, or use multiple conditional cases. Let us compare an example in Java and its rough equivalents in JavaScript.
// Example in Java try { Integer i = null; i.intValue(); // throws a NullPointerException } catch (NullPointerException error) { // Variable might be null } catch (ArithmeticException error) { // Handle problems with numbers } // Approximation #1 in JavaScript try { // Statements in which exceptions might be thrown let example = null; example.toString(); } catch (error) { if (error.type === "TypeError") { // Variable might be null } else if (error.type === "RangeError") { // Handle problems with numbers } } // Approximation #2 in JavaScript try { try { // Statements in which exceptions might be thrown let example = null; example.toString(); } catch (error) { if (error.type !== "TypeError") throw error; // Variable might be null } } catch (error) { if (error.type !== "RangeError") throw error; // Handle problems with numbers }Another aspect of exceptions are promises, which handle the exception asynchronously. Handling the exception asynchronously has the benefit that errors inside the error handler do not propagate further outwards.
new Promise(function() { throw new Error("Example error!"); }).catch(function(err) { console.log("Caught ", err); });Also observe how event handlers can tie into promises as well.
addEventListener("unhandledrejection", function(event) { console.log(event.reason); event.preventDefault(); //prevent logging the error via console.error to the console--the default behavior }); new Promise(function() { throw new Error("Example error!"); });Lastly, note that, as JavaScript uses mark-and-sweep garbage-collection, there is never any memory leakage from throw statements because the browser automatically cleans dead objects, even with circular references.
try { // Statements in which exceptions might be thrown const obj = {}; obj.selfPropExample = obj; // circular reference throw obj; } catch (error) { // Statements that execute in the event of an exception }TypeScript
In TypeScript, catch blocks cannot specify types, but this is traditionally done using instanceof. The only type annotation that can be given to the caught exception is unknown.
try { // ... } catch (e: unknown) { if (e instanceof TypeError) { // handle errors of type TypeError } else if (e instanceof SyntaxError) { // handle errors of type SyntaxError } else if (e instanceof Error) { // handle errors that extend Error } else { // handle any thrown object } } finally { // ... }Kotlin
Kotlin error handling syntax is very similar to Java.
try { // Code that may throw an exception } catch (e: ArithmeticException) { // Code for handling a kotlin.ArithmeticException // (translates to java.lang.ArithmeticException) } catch (e: Exception) { // Catches anything extending kotlin.Exception // (translates to java.lang.Exception) } catch (t: Throwable) { // Catches anything extending kotlin.Throwable // (translates to java.lang.Throwable) } finally { // Finally clause }Kotlin does not force catching checked exceptions, but can still force Java callers to catch/declare the checked exception.
import java.io.IOException @Throws(IOException::class) fun readFile() { // ... throw IOException("Failed to read file!") } // translates into // public static void readFile() throws IOException; // in the JVMKotlin supports try-expressions:
val result: Int = try { "123".toInt() // result gets 123 } catch (e: NumberFormatException) { -1 // result gets -1 }Lisp
Common Lisp
(ignore-errors (/ 1 0)) (handler-case (progn (print "enter an expression") (eval (read))) (error (e) (print e))) (unwind-protect (progn (print "enter an expression") (eval (read))) (print "This print will always be executed, similar to finally."))Lua
Lua uses the pcall and xpcall functions, with xpcall taking a function to act as a catch block.
- Predefined function
- Anonymous function
Next Generation Shell
- Defining custom exception type
- Raising exceptions
- Exception handling and propagation
- Ignoring exceptions - try without catch
- Ignoring exceptions - "tor" operator
"tor" is try-or operator. In case of any exception when evaluating the argument on the left, evaluates to the argument on the right.
1/0 tor 20 # evaluates to 20- "block" - facility to use exceptions to return a value
Objective-C
- Exception declarations
- Raising exceptions
- Exception handling and propagation
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"*)Perl 5
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.
Perl 5.005 added the ability to throw objects as well as strings. This allows 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); } };The forms shown above can sometimes fail if the global variable $@ is changed between when the exception is thrown and when it is checked in the if ($@) statement. This can happen in multi-threaded environments, or even in single-threaded environments when other code (typically called in the destruction of some object) resets the global variable before the checking code. The following example shows a way to avoid this problem (see [link removed] or ; cf. ). But at the cost of not being able to use return values:
eval { # Code that could throw an exception (using 'die') but does NOT use the return statement; 1; } or do { # Handle exception here. The exception string is in $@ };Several modules in the Comprehensive Perl Archive Network (CPAN) expand on the basic mechanism:
- Error provides a set of exception classes and allows use of the try/throw/catch/finally syntax.
- TryCatch, Try::Tiny and Nice::Try all allow the use of try/catch/finally syntax instead of boilerplate to handle exceptions correctly.
- 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.
PHP
// Exception handling is only available in PHP versions 5 and greater. try { // Code that might throw an exception throw new Exception('Invalid URL.'); } catch (FirstExceptionClass $exception) { // Code that handles this exception } catch (SecondExceptionClass $exception) { // Code that handles a different exception } finally { // Perform cleanup, whether an exception occurred or not. }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 TRYPowerShell
Version 1.0
trap [Exception] { # Statements that execute in the event of an exception } # Statements in which exceptions might be thrownVersion 2.0
Try { Import-Module ActiveDirectory } Catch [Exception1] { # Statements that execute in the event of an exception, matching the exception } Catch [Exception2],[Exception3etc] { # Statements that execute in the event of an exception, matching any of the exceptions } Catch { # Statements that execute in the event of an exception, not handled more specifically }Python
from io import TextIOWrapper f: TextIOWrapper | None = None try: f = open("aFileName", "w") 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()R
tryCatch({ stop("Here an error is signaled") # default S3-class is simpleError a subclass of error cat("This and the following lines are not executed because the error is trapped before\n") stop( structure(simpleError("mySpecialError message"),class=c("specialError","error","condition")) ) } ,specialError=function(e){ cat("catches errors of class specialError\n") } ,error=function(e){ cat("catches the default error\n") } ,finally={ cat("do some cleanup (e.g., setwd)\n") } )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] 'monikerRexx
signal on halt; do a = 1 say a do 100000 /* a delay */ end end halt: say "The program was stopped by the user" exitRuby
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 rescue # This catches all exceptions derived from StandardError retry # This executes the begin section again else # This is executed only if no exceptions were raised ensure # This is always executed, exception or not endRust
Although Rust avoids the try/catch mechanism common in most exception handling languages, it still allows for catching panics, using the std::panic::catch_unwind() function, as the default behavior in Rust when a panic occurs is to perform stack unwinding.
use std::panic; use std::thread; fn main() { let result: thread::Result<()> = panic::catch_unwind(|| { println!("This runs normally."); panic!("Something went wrong!"); // Trigger a panic }); if result.is_err() { println!("Caught the panic! The program will continue running."); } }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.
Smalltalk
[ "code that might throw an exception" ] on: ExceptionClass do: [:ex | "code that handles exception" ].The general mechanism is provided by the message on:do:. Exceptions are just normal objects that subclass Error, you throw one by creating an instance and sending it a #signal message, e.g., MyException new signal. The handling mechanism (#on:do:) is again just a normal message implemented by BlockClosure. The thrown exception is passed as a parameter to the handling block closure, and can be queried, as well as potentially sending #resume to it, to allow execution flow to continue.
Swift
Exception handling is supported since Swift 2.
enum MyException : ErrorType { case Foo(String, Int) } func someFunc() throws { throw MyException.Foo("not enough food", 2) } do { try someFunc() print("Not reached") } catch MyException.Foo(let s, let i) { print("MyException: \(s), \(i)") } catch { print("Unexpected exception : \(error)") }Tcl
if { [ catch { foo } err ] } { puts "Error: $err" }Since Tcl 8.6, there is also a try command:
try { someCommandWithExceptions } on ok {res opt} { # handle normal case. } trap ListPattern1 {err opt} { # handle exceptions with an errorcode matching ListPattern1 } trap ListPattern2 {err opt} { # ... } on error {err opt} { # handle everything else. } finally { # run whatever commands must run after the try-block. }VBScript
With New Try: On Error Resume Next 'do Something (only one statement recommended) .Catch: On Error GoTo 0: Select Case .Number Case 0 'this line is required when using 'Case Else' clause because of the lack of "Is" keyword in VBScript Case statement 'no exception Case SOME_ERRORNUMBER 'exception handling Case Else 'unknown exception End Select: End With ' *** Try Class *** Class Try Private mstrDescription Private mlngHelpContext Private mstrHelpFile Private mlngNumber Private mstrSource Public Sub Catch() mstrDescription = Err.Description mlngHelpContext = Err.HelpContext mstrHelpFile = Err.HelpFile mlngNumber = Err.Number mstrSource = Err.Source End Sub Public Property Get Source() Source = mstrSource End Property Public Property Get Number() Number = mlngNumber End Property Public Property Get HelpFile() HelpFile = mstrHelpFile End Property Public Property Get HelpContext() HelpContext = mlngHelpContext End Property Public Property Get Description() Description = mstrDescription End Property End ClassVisual Basic 6
Exception handling syntax is very similar to Basic. Error handling is local on each procedure.
On Error GoTo HandlerLabel 'When error has occurred jumps to HandlerLabel, which is defined anywhere within Function or Sub 'or On Error GoTo 0 'switch off error handling. Error causes fatal runtime error and stops application 'or On Error Resume Next 'Object Err is set, but execution continues on next command. You can still use Err object to check error state. '... Err.Raise 6 ' Generate an "Overflow" error using built-in object Err. If there is no error handler, calling procedure can catch exception by same syntax '... FinallyLabel: 'just common label within procedure (non official emulation of Finally section from other languages) 'cleanup code, always executed Exit Sub 'exits procedure 'because we are after Exit Sub statement, next code is hidden for non-error execution HandlerLabel: 'defines a common label, here used for exception handling. If Err.Number = 6 Then 'Select Case statement is typically better solution Resume FinallyLabel 'continue execution on specific label. Typically something with meaning of "Finally" in other languages 'or Resume Next 'continue execution on statement next to "Err.Raise 6" 'or Resume 'continue execution on (repeat) statement "Err.Raise 6" End If MsgBox Err.Number & " " & Err.Source & " " & Erl & " " & Err.Description & " " & Err.LastDllError 'show message box with important error properties 'Erl is VB6 built-in line number global variable (if used). Typically is used some kind of IDE Add-In, which labels every code line with number before compilation Resume FinallyLabelExample of specific (non official) implementation of exception handling, which uses object of class "Try".
With New Try: On Error Resume Next 'Create new object of class "Try" and use it. Then set this object as default. Can be "Dim T As New Try: ... ... T.Catch 'do Something (only one statement recommended) .Catch: On Error GoTo 0: Select Case .Number 'Call Try.Catch() procedure. Then switch off error handling. Then use "switch-like" statement on result of Try.Number property (value of property Err.Number of built-in Err object) Case SOME_ERRORNUMBER 'exception handling Case Is <> 0 'When Err.Number is zero, no error has occurred 'unknown exception End Select: End With ' *** Try Class *** Private mstrDescription As String Private mlngHelpContext As Long Private mstrHelpFile As String Private mlngLastDllError As Long Private mlngNumber As Long Private mstrSource As String Public Sub Catch() mstrDescription = Err.Description mlngHelpContext = Err.HelpContext mstrHelpFile = Err.HelpFile mlngLastDllError = Err.LastDllError mlngNumber = Err.Number mstrSource = Err.Source End Sub Public Property Get Source() As String Source = mstrSource End Property Public Property Get Number() As Long Number = mlngNumber End Property Public Property Get LastDllError() As Long LastDllError = mlngLastDllError End Property Public Property Get HelpFile() As String HelpFile = mstrHelpFile End Property Public Property Get HelpContext() As Long HelpContext = mlngHelpContext End Property Public Property Get Description() As String Description = mstrDescription End PropertyVisual Basic .NET
A Try block must have at least one clause Catch or Finally clause and at most one Finally clause.
Try ' code to be executed here Catch ex As Exception When condition ' Handle Exception when a specific condition is true. The exception object is stored in "ex". Catch ex As ExceptionType ' Handle Exception of a specified type (i.e. DivideByZeroException, OverflowException, etc.) Catch ex As Exception ' Handle Exception (catch all exceptions of a type not previously specified) Catch ' Handles anything that might be thrown, including non-CLR 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. End TryVisual Prolog
try % Block to protect catch TraceId do % Code to execute in the event of an exception; TraceId gives access to the exception information finally % Code will be executed regardles however the other parts behave end tryX++
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. }Sources and credits
This article is adapted from the Wikipedia article “Exception handling syntax”, written by its contributors and licensed under CC BY-SA 4.0. Fathomly has changed the layout, removed citation markers, navigation and maintenance notices, and adjusted punctuation. This adapted version is shared under the same license. For references, see the original article.
Fathomly is not affiliated with or endorsed by the Wikimedia Foundation. Spotted a problem? Tell us.