Exceptions: Difference between revisions
Langurmonkey (talk | contribs) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 14: | Line 14: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
< |
<syntaxhighlight lang="11l">T SillyError |
||
String message |
String message |
||
F (message) |
F (message) |
||
Line 22: | Line 22: | ||
X SillyError(‘egg’) |
X SillyError(‘egg’) |
||
X.catch SillyError se |
X.catch SillyError se |
||
print(se.message)</ |
print(se.message)</syntaxhighlight> |
||
=={{header|8086 Assembly}}== |
=={{header|8086 Assembly}}== |
||
Line 29: | Line 29: | ||
An exception in assembly language is often little more than just a conditional branch. Most MS-DOS system calls return the carry flag set if an error occured, and the error code will be returned in <code>AX</code>. This lets you write your own exception handler that prints a relevant error message to the screen. You'll need to read the documentation to know what each error code means. |
An exception in assembly language is often little more than just a conditional branch. Most MS-DOS system calls return the carry flag set if an error occured, and the error code will be returned in <code>AX</code>. This lets you write your own exception handler that prints a relevant error message to the screen. You'll need to read the documentation to know what each error code means. |
||
< |
<syntaxhighlight lang="asm">;syscall for creating a new file. |
||
mov dx,offset filename |
mov dx,offset filename |
||
mov cx,0 |
mov cx,0 |
||
Line 54: | Line 54: | ||
je FileAlreadyExistsError |
je FileAlreadyExistsError |
||
noError:</ |
noError:</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
'''Define an exception''' |
'''Define an exception''' |
||
<lang |
<syntaxhighlight lang="ada">Foo_Error : exception;</syntaxhighlight> |
||
'''Raise an exception''' |
'''Raise an exception''' |
||
< |
<syntaxhighlight lang="ada">procedure Foo is |
||
begin |
begin |
||
raise Foo_Error; |
raise Foo_Error; |
||
end Foo;</ |
end Foo;</syntaxhighlight> |
||
Re-raising once caught exception: |
Re-raising once caught exception: |
||
< |
<syntaxhighlight lang="ada"> ... |
||
exception |
exception |
||
when Foo_Error => |
when Foo_Error => |
||
if ... then -- Alas, cannot handle it here, |
if ... then -- Alas, cannot handle it here, |
||
raise; -- continue propagation of |
raise; -- continue propagation of |
||
end if;</ |
end if;</syntaxhighlight> |
||
'''Handle an exception''' |
'''Handle an exception''' |
||
< |
<syntaxhighlight lang="ada">procedure Call_Foo is |
||
begin |
begin |
||
Foo; |
Foo; |
||
Line 83: | Line 83: | ||
when others => |
when others => |
||
... -- this catches all other exceptions |
... -- this catches all other exceptions |
||
end Call_Foo;</ |
end Call_Foo;</syntaxhighlight> |
||
'''Ada.Exceptions'''<br> |
'''Ada.Exceptions'''<br> |
||
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: |
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: |
||
< |
<syntaxhighlight lang="ada">with Ada.Exceptions; use Ada.Exceptions; |
||
with Ada.Text_IO; use Ada.Text_IO; |
with Ada.Text_IO; use Ada.Text_IO; |
||
Line 98: | Line 98: | ||
when Error : others => |
when Error : others => |
||
Put_Line ("Something is wrong here" & Exception_Information (Error)); |
Put_Line ("Something is wrong here" & Exception_Information (Error)); |
||
end Main;</ |
end Main;</syntaxhighlight> |
||
=={{header|Aikido}}== |
=={{header|Aikido}}== |
||
Line 105: | Line 105: | ||
'''Catching exceptions'''<br> |
'''Catching exceptions'''<br> |
||
There is one <code>catch</code> clause per <code>try</code> statement. The variable caught is whatever is thrown. It does not have to be a particular type, although there is a <code>System.Exception</code> class defined for system exceptions. |
There is one <code>catch</code> clause per <code>try</code> statement. The variable caught is whatever is thrown. It does not have to be a particular type, although there is a <code>System.Exception</code> class defined for system exceptions. |
||
< |
<syntaxhighlight lang="aikido"> |
||
try { |
try { |
||
var lines = readfile ("input.txt") |
var lines = readfile ("input.txt") |
||
Line 113: | Line 113: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Throwing exceptions'''<br> |
'''Throwing exceptions'''<br> |
||
You can throw any value. |
You can throw any value. |
||
< |
<syntaxhighlight lang="aikido"> |
||
if (error) { |
if (error) { |
||
throw "Error" |
throw "Error" |
||
Line 127: | Line 127: | ||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
'''Simple Exception Throwing''' |
'''Simple Exception Throwing''' |
||
< |
<syntaxhighlight lang="aime">void |
||
throwing(void) |
throwing(void) |
||
{ |
{ |
||
Line 155: | Line 155: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>ready to catch |
<pre>ready to catch |
||
Line 162: | Line 162: | ||
caught!</pre> |
caught!</pre> |
||
'''Exception Types''' |
'''Exception Types''' |
||
< |
<syntaxhighlight lang="aime">void |
||
ft(integer a, text &s) |
ft(integer a, text &s) |
||
{ |
{ |
||
Line 200: | Line 200: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>aime: tmp/et1: 6: bad number |
<pre>aime: tmp/et1: 6: bad number |
||
Line 220: | Line 220: | ||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8 algol68g-2.8].}} |
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8 algol68g-2.8].}} |
||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}} |
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}} |
||
'''File: prelude/event_base(obj).a68'''< |
'''File: prelude/event_base(obj).a68'''<syntaxhighlight lang="algol68">COMMENT |
||
Define an general event handling mechanism on MODE OBJ: |
Define an general event handling mechanism on MODE OBJ: |
||
* try to parallel pythons exception handling flexibility |
* try to parallel pythons exception handling flexibility |
||
Line 338: | Line 338: | ||
OP (SCOPEOBJ #up scope#)VOID RESET = obj reset; |
OP (SCOPEOBJ #up scope#)VOID RESET = obj reset; |
||
SKIP</ |
SKIP</syntaxhighlight>'''File: test/event.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script # |
||
MODE OBJ=UNION(REF INT, REF REAL, REF STRING,# etc # VOID); |
MODE OBJ=UNION(REF INT, REF REAL, REF STRING,# etc # VOID); |
||
Line 385: | Line 385: | ||
RESET obj scope reset; |
RESET obj scope reset; |
||
"finally: raise the base unmendable event" RAISE obj eventb</ |
"finally: raise the base unmendable event" RAISE obj eventb</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
sum sqs: +4900 |
sum sqs: +4900 |
||
Line 426: | Line 426: | ||
'''try''' |
'''try''' |
||
< |
<syntaxhighlight lang="applescript">try |
||
set num to 1 / 0 |
set num to 1 / 0 |
||
--do something that might throw an error |
--do something that might throw an error |
||
end try</ |
end try</syntaxhighlight> |
||
'''try-on error''' |
'''try-on error''' |
||
< |
<syntaxhighlight lang="applescript">try |
||
set num to 1 / 0 |
set num to 1 / 0 |
||
--do something that might throw an error |
--do something that might throw an error |
||
Line 438: | Line 438: | ||
--errMess and number errNum are optional |
--errMess and number errNum are optional |
||
display alert "Error # " & errNum & return & errMess |
display alert "Error # " & errNum & return & errMess |
||
end try</ |
end try</syntaxhighlight> |
||
'''error''' |
'''error''' |
||
< |
<syntaxhighlight lang="applescript">error "Error message." number 2000</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Line 448: | Line 448: | ||
In [[AutoHotkey_L]] [http://l.autohotkey.net/docs/commands/Try.htm Try], [http://l.autohotkey.net/docs/commands/Catch.htm Catch], and [http://l.autohotkey.net/docs/commands/Throw.htm Throw] are available to handle exceptions.<br/> |
In [[AutoHotkey_L]] [http://l.autohotkey.net/docs/commands/Try.htm Try], [http://l.autohotkey.net/docs/commands/Catch.htm Catch], and [http://l.autohotkey.net/docs/commands/Throw.htm Throw] are available to handle exceptions.<br/> |
||
From the [http://l.autohotkey.net/docs/commands/Throw.htm Throw documentation]: |
From the [http://l.autohotkey.net/docs/commands/Throw.htm Throw documentation]: |
||
<syntaxhighlight lang="ahk">try |
|||
<lang AHK>try |
|||
BadlyCodedFunc() |
BadlyCodedFunc() |
||
catch e |
catch e |
||
Line 455: | Line 455: | ||
BadlyCodedFunc() { |
BadlyCodedFunc() { |
||
throw Exception("Fail", -1) |
throw Exception("Fail", -1) |
||
}</ |
}</syntaxhighlight> |
||
=== ErrorLevel-based exceptions === |
=== ErrorLevel-based exceptions === |
||
In [[AutoHotkey_Basic]], the only option for error-handling is using ErrorLevel |
In [[AutoHotkey_Basic]], the only option for error-handling is using ErrorLevel |
||
<syntaxhighlight lang="autohotkey">foo() |
|||
<lang AutoHotkey>foo() |
|||
If ErrorLevel |
If ErrorLevel |
||
Msgbox calling foo failed with: %ErrorLevel% |
Msgbox calling foo failed with: %ErrorLevel% |
||
Line 469: | Line 469: | ||
ErrorLevel = foo_error |
ErrorLevel = foo_error |
||
Return |
Return |
||
}</ |
}</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
< |
<syntaxhighlight lang="bbcbasic"> ON ERROR PROCerror(ERR, REPORT$) : END |
||
ERROR 100, "User-generated exception" |
ERROR 100, "User-generated exception" |
||
Line 481: | Line 481: | ||
PRINT "Error number was " ; er% |
PRINT "Error number was " ; er% |
||
PRINT "Error string was " rpt$ |
PRINT "Error string was " rpt$ |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 490: | Line 490: | ||
=={{header|blz}}== |
=={{header|blz}}== |
||
< |
<syntaxhighlight lang="blz"> |
||
try |
try |
||
1 / 0 # Throw an exception |
1 / 0 # Throw an exception |
||
Line 497: | Line 497: | ||
print("An error occured!") |
print("An error occured!") |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
Line 521: | Line 521: | ||
percolates further up, so calling the function <code>MyFunction</code> fails as well, making the whole program fail. |
percolates further up, so calling the function <code>MyFunction</code> fails as well, making the whole program fail. |
||
< |
<syntaxhighlight lang="bracmat">( ( MyFunction |
||
= someText XMLstuff |
= someText XMLstuff |
||
. ( get$!arg:?someText |
. ( get$!arg:?someText |
||
Line 537: | Line 537: | ||
) |
) |
||
& MyFunction$"Tralula.txt" |
& MyFunction$"Tralula.txt" |
||
);</ |
);</syntaxhighlight> |
||
If you copy/paste this code to the Bracmat prompt <em>without the statement delimiter <code>;</code></em>, you will see an 'F' after the output, indicating that your input failed to |
If you copy/paste this code to the Bracmat prompt <em>without the statement delimiter <code>;</code></em>, you will see an 'F' after the output, indicating that your input failed to |
||
evaluate successfully. |
evaluate successfully. |
||
Line 551: | Line 551: | ||
'''try-catch''' |
'''try-catch''' |
||
< |
<syntaxhighlight lang="c">#include <setjmp.h> |
||
enum { MY_EXCEPTION = 1 }; /* any non-zero number */ |
enum { MY_EXCEPTION = 1 }; /* any non-zero number */ |
||
Line 577: | Line 577: | ||
/* there is no way to "let the exception through" */ |
/* there is no way to "let the exception through" */ |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
With multi-thread support and nested exceptions |
With multi-thread support and nested exceptions |
||
<syntaxhighlight lang="c"> |
|||
<lang c> |
|||
#include <stdio.h> |
#include <stdio.h> |
||
#include <setjmp.h> |
#include <setjmp.h> |
||
Line 664: | Line 664: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Now all we need to do is add a finally block :) hint: it is possible |
Now all we need to do is add a finally block :) hint: it is possible |
||
Line 671: | Line 671: | ||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="csharp">public class MyException : Exception |
||
{ |
{ |
||
// data with info about exception |
// data with info about exception |
||
};</ |
};</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="csharp">void foo() |
||
{ |
{ |
||
throw MyException(); |
throw MyException(); |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="csharp">try { |
||
foo(); |
foo(); |
||
} |
} |
||
Line 693: | Line 693: | ||
{ |
{ |
||
// handle any type of exception not handled by above catches |
// handle any type of exception not handled by above catches |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 700: | Line 700: | ||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="cpp">struct MyException |
||
{ |
{ |
||
// data with info about exception |
// data with info about exception |
||
};</ |
};</syntaxhighlight> |
||
However thrown exceptions should almost always derive from <tt>std::exception</tt>. The advantage of doing so is that you can catch unknown exceptions and still get some meaningful information. There are also more specific classes like <tt>std::runtime_error</tt> which also derive from <tt>std::exception</tt>. |
However thrown exceptions should almost always derive from <tt>std::exception</tt>. The advantage of doing so is that you can catch unknown exceptions and still get some meaningful information. There are also more specific classes like <tt>std::runtime_error</tt> which also derive from <tt>std::exception</tt>. |
||
< |
<syntaxhighlight lang="cpp">#include <exception> |
||
struct MyException: std::exception |
struct MyException: std::exception |
||
{ |
{ |
||
virtual const char* what() const noexcept { return "description"; } |
virtual const char* what() const noexcept { return "description"; } |
||
}</ |
}</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="cpp">void foo() |
||
{ |
{ |
||
throw MyException(); |
throw MyException(); |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="cpp">try { |
||
foo(); |
foo(); |
||
} |
} |
||
Line 736: | Line 736: | ||
{ |
{ |
||
// handle any type of exception not handled by above catches |
// handle any type of exception not handled by above catches |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Expression handling in Clojure is basically like Java in S-expressions: |
Expression handling in Clojure is basically like Java in S-expressions: |
||
< |
<syntaxhighlight lang="clojure">(try |
||
(if (> (rand) 0.5) |
(if (> (rand) 0.5) |
||
(throw (RuntimeException. "oops!")) |
(throw (RuntimeException. "oops!")) |
||
Line 747: | Line 747: | ||
(println e) |
(println e) |
||
(finally |
(finally |
||
(println "always see this"))</ |
(println "always see this"))</syntaxhighlight> |
||
=={{header|ColdFusion}}== |
=={{header|ColdFusion}}== |
||
Line 754: | Line 754: | ||
inside <cfscript>: |
inside <cfscript>: |
||
< |
<syntaxhighlight lang="cfm">try { |
||
foo(); |
foo(); |
||
} catch (Any e) { |
} catch (Any e) { |
||
// handle exception e |
// handle exception e |
||
}</ |
}</syntaxhighlight> |
||
otherwise: |
otherwise: |
||
< |
<syntaxhighlight lang="cfm"><cftry> |
||
<cfcatch type="Database|..."> |
<cfcatch type="Database|..."> |
||
</cfcatch> |
</cfcatch> |
||
</cftry></ |
</cftry></syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 770: | Line 770: | ||
The Common Lisp condition system allows much more control over condition signaling and condition handling than many exception-based systems. The following example, however, simply defines a condition type, <code>unexpected-odd-number</code>, defines a function <code>get-number</code> which generates a random number, returning it if it is even, but signaling an <code>unexpected-odd-number</code> condition if it is odd. The function <code>get-even-number</code> uses <code>[http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm handler-case]</code> to call <code>get-number</code> returning its result if no condition is signaled, and, in the case that an <code>unexpected-odd-number</code> condition is signaled, returning one plus the odd number. |
The Common Lisp condition system allows much more control over condition signaling and condition handling than many exception-based systems. The following example, however, simply defines a condition type, <code>unexpected-odd-number</code>, defines a function <code>get-number</code> which generates a random number, returning it if it is even, but signaling an <code>unexpected-odd-number</code> condition if it is odd. The function <code>get-even-number</code> uses <code>[http://www.lispworks.com/documentation/HyperSpec/Body/m_hand_1.htm handler-case]</code> to call <code>get-number</code> returning its result if no condition is signaled, and, in the case that an <code>unexpected-odd-number</code> condition is signaled, returning one plus the odd number. |
||
< |
<syntaxhighlight lang="lisp">(define-condition unexpected-odd-number (error) |
||
((number :reader number :initarg :number)) |
((number :reader number :initarg :number)) |
||
(:report (lambda (condition stream) |
(:report (lambda (condition stream) |
||
Line 783: | Line 783: | ||
(handler-case (get-number) |
(handler-case (get-number) |
||
(unexpected-odd-number (condition) |
(unexpected-odd-number (condition) |
||
(1+ (number condition)))))</ |
(1+ (number condition)))))</syntaxhighlight> |
||
A good introduction to Lisp's condition system is the chapter [http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html Beyond Exception Handling: Conditions and Restarts] from Peter Seibel's [http://gigamonkeys.com/book/ Practical Common Lisp]. |
A good introduction to Lisp's condition system is the chapter [http://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html Beyond Exception Handling: Conditions and Restarts] from Peter Seibel's [http://gigamonkeys.com/book/ Practical Common Lisp]. |
||
Line 790: | Line 790: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
/// Throw Exceptions |
/// Throw Exceptions |
||
Line 824: | Line 824: | ||
void main() { |
void main() { |
||
test4(); |
test4(); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
'''Throw Exceptions''' |
'''Throw Exceptions''' |
||
< |
<syntaxhighlight lang="delphi">procedure test; |
||
begin |
begin |
||
raise Exception.Create('Sample Exception'); |
raise Exception.Create('Sample Exception'); |
||
end;</ |
end;</syntaxhighlight> |
||
'''Catch Exceptions''' |
'''Catch Exceptions''' |
||
< |
<syntaxhighlight lang="delphi">procedure test2; |
||
begin |
begin |
||
try |
try |
||
Line 843: | Line 843: | ||
raise; // Rethrowing |
raise; // Rethrowing |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
'''Ways to implement finally''' |
'''Ways to implement finally''' |
||
< |
<syntaxhighlight lang="delphi">procedure test3; |
||
begin |
begin |
||
try |
try |
||
Line 853: | Line 853: | ||
ShowMessage('test3 finally'); |
ShowMessage('test3 finally'); |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Dyalect}}== |
=={{header|Dyalect}}== |
||
< |
<syntaxhighlight lang="dyalect">func Integer.Add(x) { |
||
throw @NegativesNotAllowed(x) when x < 0 |
throw @NegativesNotAllowed(x) when x < 0 |
||
this + x |
this + x |
||
Line 866: | Line 866: | ||
} catch { |
} catch { |
||
@NegativesNotAllowed(x) => print("Negative number: \(x)") |
@NegativesNotAllowed(x) => print("Negative number: \(x)") |
||
}</ |
}</syntaxhighlight> |
||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
'''Throw Exceptions''' |
'''Throw Exceptions''' |
||
< |
<syntaxhighlight lang="delphi">procedure Test; |
||
begin |
begin |
||
raise Exception.Create('Sample Exception'); |
raise Exception.Create('Sample Exception'); |
||
end;</ |
end;</syntaxhighlight> |
||
'''Catch Exceptions''' |
'''Catch Exceptions''' |
||
< |
<syntaxhighlight lang="delphi">procedure Test2; |
||
begin |
begin |
||
try |
try |
||
Line 887: | Line 887: | ||
end; |
end; |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
'''Ways to implement finally''' |
'''Ways to implement finally''' |
||
< |
<syntaxhighlight lang="delphi">procedure Test3; |
||
begin |
begin |
||
try |
try |
||
Line 897: | Line 897: | ||
PrintLn('Test3 finally'); |
PrintLn('Test3 finally'); |
||
end; |
end; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Déjà Vu}}== |
=={{header|Déjà Vu}}== |
||
< |
<syntaxhighlight lang="dejavu">stuff-going-wrong: |
||
raise :value-error |
raise :value-error |
||
Line 907: | Line 907: | ||
stuff-going-wrong |
stuff-going-wrong |
||
catch value-error: |
catch value-error: |
||
!print "Whoops!"</ |
!print "Whoops!"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Whoops!</pre> |
<pre>Whoops!</pre> |
||
Line 927: | Line 927: | ||
<code>throw</code> is the built-in ''function'' which throws exceptions in the conventional sense: control goes to the <code>catch</code> block of the most recently entered <code>try</code>/<code>catch</code> construct. |
<code>throw</code> is the built-in ''function'' which throws exceptions in the conventional sense: control goes to the <code>catch</code> block of the most recently entered <code>try</code>/<code>catch</code> construct. |
||
< |
<syntaxhighlight lang="e">def nameOf(arg :int) { |
||
if (arg == 43) { |
if (arg == 43) { |
||
return "Bob" |
return "Bob" |
||
Line 941: | Line 941: | ||
return ["notok", exceptionObj] |
return ["notok", exceptionObj] |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="e">? catching(42) |
||
# value: ["not ok", problem: Who?] |
# value: ["not ok", problem: Who?] |
||
Line 950: | Line 950: | ||
? catching(45.7) |
? catching(45.7) |
||
# value: ["not ok", problem: the float64 45.7 doesn't coerce to an int]</ |
# value: ["not ok", problem: the float64 45.7 doesn't coerce to an int]</syntaxhighlight> |
||
However, there is a problem here: exceptions accidentally produced or uncaught from inside a given module can lead to the calling program getting information about the internals that it shouldn't have (possibly a security problem). As a result of this, we are planning to move to a 'sealed exception' model where throw and catch have the same control flow, but only debuggers can see any information in a ''caught'' exception other than "a throw happened". For situations where the caller ''should'' have information about what happened, the ejector mechanism will be used. |
However, there is a problem here: exceptions accidentally produced or uncaught from inside a given module can lead to the calling program getting information about the internals that it shouldn't have (possibly a security problem). As a result of this, we are planning to move to a 'sealed exception' model where throw and catch have the same control flow, but only debuggers can see any information in a ''caught'' exception other than "a throw happened". For situations where the caller ''should'' have information about what happened, the ejector mechanism will be used. |
||
Line 962: | Line 962: | ||
The above code rewritten to use ejectors: |
The above code rewritten to use ejectors: |
||
< |
<syntaxhighlight lang="e">def nameOf(arg :int, ejector) { |
||
if (arg == 43) { |
if (arg == 43) { |
||
return "Bob" |
return "Bob" |
||
Line 976: | Line 976: | ||
return ["notok", exceptionObj] |
return ["notok", exceptionObj] |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="e">? catching(42) |
||
# value: ["not ok", problem: Who?] |
# value: ["not ok", problem: Who?] |
||
Line 985: | Line 985: | ||
? catching(45.7) |
? catching(45.7) |
||
# problem: the float64 45.7 doesn't coerce to an int</ |
# problem: the float64 45.7 doesn't coerce to an int</syntaxhighlight> |
||
Note that the escape-catch block does ''not'' catch the coercion error resulting from passing a float64 instead of an int, since that is an (implicit) throw. |
Note that the escape-catch block does ''not'' catch the coercion error resulting from passing a float64 instead of an int, since that is an (implicit) throw. |
||
Line 995: | Line 995: | ||
For example, suppose we have nameOf written as follows: |
For example, suppose we have nameOf written as follows: |
||
< |
<syntaxhighlight lang="e">var nameTable := null |
||
def nameOf(arg :int, ejector) { |
def nameOf(arg :int, ejector) { |
||
if (nameTable == null) { |
if (nameTable == null) { |
||
Line 1,005: | Line 1,005: | ||
ejector(makeNotFoundException("Who?")) |
ejector(makeNotFoundException("Who?")) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Suppose that loading the parser, or reading the file, throws a NotFoundException (note this exception type was made up for this example). Even though it is of the same type as the "Who?" exception, it will not be caught by the caller's escape/catch block since it was not passed via the ejector, whereas a traditional "try { ... } catch ex :NotFoundException { ... }" as in other languages would, leading to incorrect handling of the error. |
Suppose that loading the parser, or reading the file, throws a NotFoundException (note this exception type was made up for this example). Even though it is of the same type as the "Who?" exception, it will not be caught by the caller's escape/catch block since it was not passed via the ejector, whereas a traditional "try { ... } catch ex :NotFoundException { ... }" as in other languages would, leading to incorrect handling of the error. |
||
Line 1,012: | Line 1,012: | ||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="elena">class MyException : Exception |
||
{ |
{ |
||
constructor new() |
constructor new() |
||
<= new("MyException raised"); |
<= new("MyException raised"); |
||
}</ |
}</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="elena">foo() |
||
{ |
{ |
||
MyException.raise() |
MyException.raise() |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="elena">try |
||
{ |
{ |
||
o.foo() |
o.foo() |
||
Line 1,033: | Line 1,033: | ||
{ |
{ |
||
// handle exceptions of type MyException and derived |
// handle exceptions of type MyException and derived |
||
}</ |
}</syntaxhighlight> |
||
'''Catching any exception''' |
'''Catching any exception''' |
||
< |
<syntaxhighlight lang="elena">o.foo() | on:(e) |
||
{ |
{ |
||
// handle any type of exception |
// handle any type of exception |
||
};</ |
};</syntaxhighlight> |
||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
<syntaxhighlight lang="erlang"> |
|||
<lang Erlang> |
|||
-module( exceptions ). |
-module( exceptions ). |
||
Line 1,055: | Line 1,055: | ||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,065: | Line 1,065: | ||
'''Throw Exceptions''' |
'''Throw Exceptions''' |
||
< |
<syntaxhighlight lang="factor">"Install Linux, Problem Solved" throw |
||
TUPLE: velociraptor ; |
TUPLE: velociraptor ; |
||
\ velociraptor new throw</ |
\ velociraptor new throw</syntaxhighlight> |
||
Or a shorthand for this: |
Or a shorthand for this: |
||
< |
<syntaxhighlight lang="factor">ERROR: velociraptor ; |
||
velociraptor</ |
velociraptor</syntaxhighlight> |
||
'''Catch Exceptions''' |
'''Catch Exceptions''' |
||
< |
<syntaxhighlight lang="factor">! Preferred exception handling |
||
: try-foo |
: try-foo |
||
[ foo ] [ foo-failed ] recover ; |
[ foo ] [ foo-failed ] recover ; |
||
Line 1,086: | Line 1,086: | ||
[ "Fail" throw ] catch ! returns "Fail" |
[ "Fail" throw ] catch ! returns "Fail" |
||
[ "Hi" print ] catch ! returns f (looks the same as throwing f; don't throw f) |
[ "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</ |
[ f throw ] catch ! returns f, bad! use recover or cleanup instead</syntaxhighlight> |
||
=={{header|Fancy}}== |
=={{header|Fancy}}== |
||
< |
<syntaxhighlight lang="fancy"># define custom exception class |
||
# StandardError is base class for all exception classes |
# StandardError is base class for all exception classes |
||
class MyError : StandardError { |
class MyError : StandardError { |
||
Line 1,108: | Line 1,108: | ||
# this will always be executed (as in e.g. Java) |
# this will always be executed (as in e.g. Java) |
||
"This is how exception handling in Fancy works :)" println |
"This is how exception handling in Fancy works :)" println |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
< |
<syntaxhighlight lang="fantom"> |
||
// Create a new error class by subclassing sys::Err |
// Create a new error class by subclassing sys::Err |
||
const class SpecialErr : Err |
const class SpecialErr : Err |
||
Line 1,136: | Line 1,136: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,148: | Line 1,148: | ||
'''Throw Exceptions''' |
'''Throw Exceptions''' |
||
< |
<syntaxhighlight lang="forth">: f ( -- ) 1 throw ." f " ; \ will throw a "1" |
||
: g ( -- ) 0 throw ." g " ; \ does not throw</ |
: g ( -- ) 0 throw ." g " ; \ does not throw</syntaxhighlight> |
||
'''Catch Exceptions''' |
'''Catch Exceptions''' |
||
< |
<syntaxhighlight lang="forth">: report ( n -- ) ?dup if ." caught " . else ." no throw" then ; |
||
: test ( -- ) |
: test ( -- ) |
||
['] f catch report |
['] f catch report |
||
['] g catch report ;</ |
['] g catch report ;</syntaxhighlight> |
||
test example. (Output shown in bold) |
test example. (Output shown in bold) |
||
< |
<syntaxhighlight lang="forth">cr test |
||
'''caught 1 g no throw ok'''</ |
'''caught 1 g no throw ok'''</syntaxhighlight> |
||
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: |
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: |
||
< |
<syntaxhighlight lang="forth">10 ['] myfun catch if drop then</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
FreeBASIC does not support exceptions or the Try/Catch/Finally statement, as such. |
FreeBASIC does not support exceptions or the Try/Catch/Finally statement, as such. |
||
However, you can use the Err() function, together with a Switch statement, to provide somewhat similar functionality: |
However, you can use the Err() function, together with a Switch statement, to provide somewhat similar functionality: |
||
< |
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
||
Enum ErrorType |
Enum ErrorType |
||
Line 1,195: | Line 1,195: | ||
Print |
Print |
||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,204: | Line 1,204: | ||
=={{header|Gambas}}== |
=={{header|Gambas}}== |
||
'''[https://gambas-playground.proko.eu/?gist=c3abec93bc7f135203f1f7582f5c3a19 Click this link to run this code]''' |
'''[https://gambas-playground.proko.eu/?gist=c3abec93bc7f135203f1f7582f5c3a19 Click this link to run this code]''' |
||
< |
<syntaxhighlight lang="gambas">Public Sub Main() |
||
Dim iInteger As Integer |
Dim iInteger As Integer |
||
Line 1,233: | Line 1,233: | ||
Print Error.Text |
Print Error.Text |
||
End</ |
End</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 1,248: | Line 1,248: | ||
<tt>recover()</tt> needs to be called in a "deferred" function call, otherwise it will have no effect. <tt>defer</tt> delays the function call until the current function returns (or fails). |
<tt>recover()</tt> needs to be called in a "deferred" function call, otherwise it will have no effect. <tt>defer</tt> delays the function call until the current function returns (or fails). |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 1,269: | Line 1,269: | ||
foo() |
foo() |
||
fmt.Println("glad that's over.") |
fmt.Println("glad that's over.") |
||
}</ |
}</syntaxhighlight>[http://play.golang.org/p/9ymYAmOMIP Run in the Go Playground]. |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,285: | Line 1,285: | ||
'''Throw exceptions'''<br> |
'''Throw exceptions'''<br> |
||
In the context of the IO monad, use "throwIO" to throw exceptions; the expression will return any type: |
In the context of the IO monad, use "throwIO" to throw exceptions; the expression will return any type: |
||
< |
<syntaxhighlight lang="haskell">do {- ... -} |
||
throwIO SomeException</ |
throwIO SomeException</syntaxhighlight> |
||
In purely functional context, use "throw" to throw exceptions; the expression will match any type: |
In purely functional context, use "throw" to throw exceptions; the expression will match any type: |
||
< |
<syntaxhighlight lang="haskell">if condition then 3 |
||
else throw SomeException</ |
else throw SomeException</syntaxhighlight> |
||
To throw a user-defined exception, use "throwDyn": |
To throw a user-defined exception, use "throwDyn": |
||
< |
<syntaxhighlight lang="haskell">if condition then 3 |
||
else throwDyn myException</ |
else throwDyn myException</syntaxhighlight> |
||
'''Catching exceptions'''<br> |
'''Catching exceptions'''<br> |
||
The "catch" function performs the whole try-catch stuff. It is usually used in infix style: |
The "catch" function performs the whole try-catch stuff. It is usually used in infix style: |
||
pattern-matches on the exception type and argument: |
pattern-matches on the exception type and argument: |
||
< |
<syntaxhighlight lang="haskell">do |
||
{- do IO computations here -} |
{- do IO computations here -} |
||
`catch` \ex -> do |
`catch` \ex -> do |
||
{- handle exception "ex" here -}</ |
{- handle exception "ex" here -}</syntaxhighlight> |
||
Note: Control.Exception's "catch" is different than Prelude's "catch". |
Note: Control.Exception's "catch" is different than Prelude's "catch". |
||
To catch a user-defined exception, use "catchDyn": |
To catch a user-defined exception, use "catchDyn": |
||
< |
<syntaxhighlight lang="haskell">do |
||
{- do IO computations here -} |
{- do IO computations here -} |
||
`catchDyn` \ex -> do |
`catchDyn` \ex -> do |
||
{- handle exception "ex" here -}</ |
{- handle exception "ex" here -}</syntaxhighlight> |
||
=={{header|HolyC}}== |
=={{header|HolyC}}== |
||
Line 1,317: | Line 1,317: | ||
The <code>catch</code> block does not have the capability to differentiate between specific exceptions. Instead, all exceptions for a <code>try</code> block are handled by a single <code>catch</code> block. |
The <code>catch</code> block does not have the capability to differentiate between specific exceptions. Instead, all exceptions for a <code>try</code> block are handled by a single <code>catch</code> block. |
||
< |
<syntaxhighlight lang="holyc">try { |
||
U8 *err = 'Error'; |
U8 *err = 'Error'; |
||
throw(err); // throw exception |
throw(err); // throw exception |
||
Line 1,324: | Line 1,324: | ||
Print("Raised 'Error'"); |
Print("Raised 'Error'"); |
||
PutExcept; // print the exception and stack trace |
PutExcept; // print the exception and stack trace |
||
}</ |
}</syntaxhighlight> |
||
==Icon and {{header|Unicon}}== |
==Icon and {{header|Unicon}}== |
||
Line 1,334: | Line 1,334: | ||
support exceptions.</i> |
support exceptions.</i> |
||
< |
<syntaxhighlight lang="unicon">import Exceptions |
||
procedure main(A) |
procedure main(A) |
||
Line 1,350: | Line 1,350: | ||
if numeric(i) = 3 then Exception().throw("bad value of "||i) |
if numeric(i) = 3 then Exception().throw("bad value of "||i) |
||
return i |
return i |
||
end</ |
end</syntaxhighlight> |
||
A sample run is: |
A sample run is: |
||
Line 1,376: | Line 1,376: | ||
An exception in an explicit definition can be detected with <tt>try.</tt> and <tt>catcht.</tt> and can be thrown with <tt> throw. </tt> as seen below. |
An exception in an explicit definition can be detected with <tt>try.</tt> and <tt>catcht.</tt> and can be thrown with <tt> throw. </tt> as seen below. |
||
< |
<syntaxhighlight lang="j"> pickyPicky =: verb define |
||
if. y-:'bad argument' do. |
if. y-:'bad argument' do. |
||
throw. |
throw. |
||
Line 1,393: | Line 1,393: | ||
tryThis 'bad argument' |
tryThis 'bad argument' |
||
Uh oh!</ |
Uh oh!</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
Line 1,399: | Line 1,399: | ||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="java">//Checked exception |
||
public class MyException extends Exception { |
public class MyException extends Exception { |
||
//Put specific info in here |
//Put specific info in here |
||
Line 1,405: | Line 1,405: | ||
//Unchecked exception |
//Unchecked exception |
||
public class MyRuntimeException extends RuntimeException {}</ |
public class MyRuntimeException extends RuntimeException {}</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="java">public void fooChecked() throws MyException { |
||
throw new MyException(); |
throw new MyException(); |
||
} |
} |
||
Line 1,414: | Line 1,414: | ||
public void fooUnchecked() { |
public void fooUnchecked() { |
||
throw new MyRuntimeException(); |
throw new MyRuntimeException(); |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="java">try { |
||
fooChecked(); |
fooChecked(); |
||
} |
} |
||
Line 1,431: | Line 1,431: | ||
finally { |
finally { |
||
//This code is always executed after exiting the try block |
//This code is always executed after exiting the try block |
||
}</ |
}</syntaxhighlight> |
||
{{works with|Java|7+}} |
{{works with|Java|7+}} |
||
Java 7 added "multicatch" and "smart rethrow". |
Java 7 added "multicatch" and "smart rethrow". |
||
< |
<syntaxhighlight lang="java5">public void foo() throws UnsupportedDataTypeException{ |
||
try{ |
try{ |
||
throwsNumberFormatException(); |
throwsNumberFormatException(); |
||
Line 1,446: | Line 1,446: | ||
throw e; |
throw e; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
In previous versions of Java, <code>foo()</code> would have to declare that it throws an <code>IOException</code>. The "smart rethrow" recognizes that the only checked exception that can result in the rethrow ("<code>throw e;</code>") is an <code>UnsupportedDataTypeException</code>. The last catch block will still catch any other unchecked <code>IOException</code>s and rethrow them, but <code>foo()</code> only needs to declare that <code>UnsupportedDataTypeException</code>s are thrown from it since that's the only checked exception that can cause a rethrow. |
In previous versions of Java, <code>foo()</code> would have to declare that it throws an <code>IOException</code>. The "smart rethrow" recognizes that the only checked exception that can result in the rethrow ("<code>throw e;</code>") is an <code>UnsupportedDataTypeException</code>. The last catch block will still catch any other unchecked <code>IOException</code>s and rethrow them, but <code>foo()</code> only needs to declare that <code>UnsupportedDataTypeException</code>s are thrown from it since that's the only checked exception that can cause a rethrow. |
||
Line 1,455: | Line 1,455: | ||
'''Throwing exceptions''' |
'''Throwing exceptions''' |
||
< |
<syntaxhighlight lang="javascript">function doStuff() { |
||
throw new Error('Not implemented!'); |
throw new Error('Not implemented!'); |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="javascript">try { |
||
element.attachEvent('onclick', doStuff); |
element.attachEvent('onclick', doStuff); |
||
} |
} |
||
Line 1,469: | Line 1,469: | ||
finally { |
finally { |
||
eventSetup = true; |
eventSetup = true; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
Line 1,479: | Line 1,479: | ||
The "try" clause takes the form: |
The "try" clause takes the form: |
||
<lang |
<syntaxhighlight lang="jq">try FILTER catch CATCHER</syntaxhighlight> |
||
where FILTER and CATCHER may be any jq expressions. |
where FILTER and CATCHER may be any jq expressions. |
||
Line 1,485: | Line 1,485: | ||
'''Example''': |
'''Example''': |
||
< |
<syntaxhighlight lang="jq">def division(a;b): |
||
def abs: if . < 0 then -. else . end; |
def abs: if . < 0 then -. else . end; |
||
if a == 0 and b == 0 then error("0/0") |
if a == 0 and b == 0 then error("0/0") |
||
Line 1,498: | Line 1,498: | ||
elif . == "division by 0" then null |
elif . == "division by 0" then null |
||
else "\(.): \(a) / \(b)" |
else "\(.): \(a) / \(b)" |
||
end;</ |
end;</syntaxhighlight> |
||
# test(0;0) # produces 0 |
# test(0;0) # produces 0 |
||
Line 1,507: | Line 1,507: | ||
{{works with|Julia|0.6}} |
{{works with|Julia|0.6}} |
||
< |
<syntaxhighlight lang="julia">function extendedsqrt(x) |
||
try sqrt(x) |
try sqrt(x) |
||
catch |
catch |
||
Line 1,520: | Line 1,520: | ||
@show extendedsqrt(1) # 1 |
@show extendedsqrt(1) # 1 |
||
@show extendedsqrt(-1) # 0.0 + 1.0im |
@show extendedsqrt(-1) # 0.0 + 1.0im |
||
@show extendedsqrt('x') # ERROR: DomainError</ |
@show extendedsqrt('x') # ERROR: DomainError</syntaxhighlight> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
// In Kotlin all Exception classes derive from Throwable and, by convention, end with the word 'Exception' |
// In Kotlin all Exception classes derive from Throwable and, by convention, end with the word 'Exception' |
||
Line 1,545: | Line 1,545: | ||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
goo() |
goo() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,564: | Line 1,564: | ||
Exceptions in langur are hashes guaranteed to contain certain fields, even if they're empty. |
Exceptions in langur are hashes guaranteed to contain certain fields, even if they're empty. |
||
< |
<syntaxhighlight lang="langur"># do something |
||
throw "not a math exception" |
throw "not a math exception" |
||
Line 1,577: | Line 1,577: | ||
# no exception |
# no exception |
||
... |
... |
||
}</ |
}</syntaxhighlight> |
||
An else section on a catch is optional. As of 0.7, you can also use else if on a catch. |
An else section on a catch is optional. As of 0.7, you can also use else if on a catch. |
||
Line 1,586: | Line 1,586: | ||
A shortened catch does not allow an else section (action for no exception). |
A shortened catch does not allow an else section (action for no exception). |
||
< |
<syntaxhighlight lang="langur">100 / 0 |
||
catch if _err["cat"] == "math" { |
catch if _err["cat"] == "math" { |
||
Line 1,593: | Line 1,593: | ||
} else { |
} else { |
||
throw |
throw |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="langur">val .safediv = f { .x / .y ; catch 0 } |
||
.safediv(7, 7) # 1 |
.safediv(7, 7) # 1 |
||
.safediv(7, 0) # 0</ |
.safediv(7, 0) # 0</syntaxhighlight> |
||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
< |
<syntaxhighlight lang="lasso">protect => { |
||
handle_error => { |
handle_error => { |
||
// do something else |
// do something else |
||
} |
} |
||
fail(-1,'Oops') |
fail(-1,'Oops') |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Lingo has no try...catch mechanism. A script error will always end execution of the current call stack. There is however a mechanism that prevents that script errors quit the execution of the current movie/projector: you can set up an "alertHook" that is called when such errors occur. This alertHook can then e.g. log the error to a file or database, and if it returns 1, the movie/projector continues to play: |
Lingo has no try...catch mechanism. A script error will always end execution of the current call stack. There is however a mechanism that prevents that script errors quit the execution of the current movie/projector: you can set up an "alertHook" that is called when such errors occur. This alertHook can then e.g. log the error to a file or database, and if it returns 1, the movie/projector continues to play: |
||
< |
<syntaxhighlight lang="lingo">-- parent script "ErrorHandler" |
||
on alertHook (me, errorType, errorMessage, alertType) |
on alertHook (me, errorType, errorMessage, alertType) |
||
Line 1,628: | Line 1,628: | ||
return 1 -- continues movie playback, no error dialog |
return 1 -- continues movie playback, no error dialog |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="lingo">-- in a movie script |
||
on prepareMovie |
on prepareMovie |
||
_player.alertHook = script("ErrorHandler") |
_player.alertHook = script("ErrorHandler") |
||
end</ |
end</syntaxhighlight> |
||
In terms of the behavior described above, a "throw" command triggering custom errors that behave exactly like real script errors can be implemented like this: |
In terms of the behavior described above, a "throw" command triggering custom errors that behave exactly like real script errors can be implemented like this: |
||
< |
<syntaxhighlight lang="lingo">-- in a movie script |
||
-- usage: throw("Custom error 23") |
-- usage: throw("Custom error 23") |
||
on throw (msg) |
on throw (msg) |
||
_player.alertHook.alertHook("Script runtime error", msg, #script) |
_player.alertHook.alertHook("Script runtime error", msg, #script) |
||
abort() -- exits call stack |
abort() -- exits call stack |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
{{works with|UCB Logo}} |
{{works with|UCB Logo}} |
||
< |
<syntaxhighlight lang="logo">to div.checked :a :b |
||
if :b = 0 [(throw "divzero 0)] |
if :b = 0 [(throw "divzero 0)] |
||
output :a / :b |
output :a / :b |
||
Line 1,652: | Line 1,652: | ||
to div.safely :a :b |
to div.safely :a :b |
||
output catch "divzero [div.checked :a :b] |
output catch "divzero [div.checked :a :b] |
||
end</ |
end</syntaxhighlight> |
||
There are also some predefined exceptions: |
There are also some predefined exceptions: |
||
* '''throw "toplevel''' returns to the interactive prompt if uncaught (like control-C) |
* '''throw "toplevel''' returns to the interactive prompt if uncaught (like control-C) |
||
Line 1,661: | Line 1,661: | ||
=={{header|Logtalk}}== |
=={{header|Logtalk}}== |
||
Logtalk exception-handling mechanism is based on the catch/3 and throw/1 predicates inherited from Prolog: |
Logtalk exception-handling mechanism is based on the catch/3 and throw/1 predicates inherited from Prolog: |
||
< |
<syntaxhighlight lang="logtalk"> |
||
:- object(exceptions). |
:- object(exceptions). |
||
Line 1,685: | Line 1,685: | ||
:- end_object. |
:- end_object. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,702: | Line 1,702: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
'''Throwing an Exception'''<br> |
'''Throwing an Exception'''<br> |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
error("Something bad happened!") |
error("Something bad happened!") |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Catching Exceptions'''<br> |
'''Catching Exceptions'''<br> |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
function throw_error() |
function throw_error() |
||
error("Whoops") |
error("Whoops") |
||
Line 1,719: | Line 1,719: | ||
status, errmsg = pcall(throw_error) |
status, errmsg = pcall(throw_error) |
||
print("errmsg = ", errmsg) |
print("errmsg = ", errmsg) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note that `pcall` passes every argument after the function object or function name to said function:<br /> |
Note that `pcall` passes every argument after the function object or function name to said function:<br /> |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
function throw_error_with_argment(argument) |
function throw_error_with_argment(argument) |
||
error(string.format("Whoops! argument = %s", argument)) |
error(string.format("Whoops! argument = %s", argument)) |
||
Line 1,731: | Line 1,731: | ||
status, errmsg = pcall(throw_error_with_argment, "foobar 123") |
status, errmsg = pcall(throw_error_with_argment, "foobar 123") |
||
print("errmsg = ", errmsg) |
print("errmsg = ", errmsg) |
||
</syntaxhighlight> |
|||
</lang> |
|||
If a function does not throw an error, 'errmsg' (which might be called 'returned' as well) contains the value(s) returned from the function:<br /> |
If a function does not throw an error, 'errmsg' (which might be called 'returned' as well) contains the value(s) returned from the function:<br /> |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
function throw_error_with_argment(argument) |
function throw_error_with_argment(argument) |
||
return "hello!" |
return "hello!" |
||
Line 1,741: | Line 1,741: | ||
status, errmsg = pcall(throw_error_with_argment, "foobar 123") |
status, errmsg = pcall(throw_error_with_argment, "foobar 123") |
||
print("errmsg = ", errmsg) |
print("errmsg = ", errmsg) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Errors { |
Module Errors { |
||
Module Check { |
Module Check { |
||
Line 1,767: | Line 1,767: | ||
Errors |
Errors |
||
Print Error$="" |
Print Error$="" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,782: | Line 1,782: | ||
fail.mk |
fail.mk |
||
< |
<syntaxhighlight lang="make">all: |
||
false</ |
false</syntaxhighlight> |
||
Using -@ to ignore the exception. |
Using -@ to ignore the exception. |
||
Line 1,789: | Line 1,789: | ||
catch.mk |
catch.mk |
||
< |
<syntaxhighlight lang="make">all: |
||
-@make -f fail.mk</ |
-@make -f fail.mk</syntaxhighlight> |
||
Using explicit exit 0 to ignore the exception. |
Using explicit exit 0 to ignore the exception. |
||
Line 1,796: | Line 1,796: | ||
catch.mk |
catch.mk |
||
< |
<syntaxhighlight lang="make">all: |
||
make -f fail.mk; exit 0</ |
make -f fail.mk; exit 0</syntaxhighlight> |
||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
<syntaxhighlight lang="maple"> |
|||
<lang Maple> |
|||
errorproc:=proc(n) |
errorproc:=proc(n) |
||
local a; |
local a; |
||
Line 1,809: | Line 1,809: | ||
end try; |
end try; |
||
end proc; |
end proc; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">f[x_] := If[x > 10, Throw[overflow], x!] |
||
Example usage : |
Example usage : |
||
Line 1,819: | Line 1,819: | ||
Catch[f[2] + f[3]] |
Catch[f[2] + f[3]] |
||
-> 8</ |
-> 8</syntaxhighlight> |
||
=={{header|MATLAB}}== |
=={{header|MATLAB}}== |
||
Line 1,825: | Line 1,825: | ||
Sample usage: |
Sample usage: |
||
< |
<syntaxhighlight lang="matlab">>> error 'Help' |
||
??? Help</ |
??? Help</syntaxhighlight> |
||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
Line 1,832: | Line 1,832: | ||
'''Defining exceptions'''<br> |
'''Defining exceptions'''<br> |
||
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. |
||
< |
<syntaxhighlight lang="modula3">EXCEPTION EndOfFile; |
||
EXCEPTION Error(TEXT);</ |
EXCEPTION Error(TEXT);</syntaxhighlight> |
||
'''Throw exceptions'''<br> |
'''Throw exceptions'''<br> |
||
Exceptions can be bound to procedures using RAISES: |
Exceptions can be bound to procedures using RAISES: |
||
< |
<syntaxhighlight lang="modula3">PROCEDURE Foo() RAISES { EndOfFile } = |
||
... |
... |
||
RAISE EndOfFile; |
RAISE EndOfFile; |
||
...</ |
...</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="modula3">TRY |
||
Foo(); |
Foo(); |
||
EXCEPT |
EXCEPT |
||
| EndOfFile => HandleFoo(); |
| EndOfFile => HandleFoo(); |
||
END;</ |
END;</syntaxhighlight> |
||
Modula-3 also has a FINALLY keyword: |
Modula-3 also has a FINALLY keyword: |
||
< |
<syntaxhighlight lang="modula3">TRY |
||
Foo(); |
Foo(); |
||
FINALLY |
FINALLY |
||
CleanupFoo(); (* always executed *) |
CleanupFoo(); (* always executed *) |
||
END;</ |
END;</syntaxhighlight> |
||
=={{header|MOO}}== |
=={{header|MOO}}== |
||
Line 1,860: | Line 1,860: | ||
'''Throw exceptions'''<br> |
'''Throw exceptions'''<br> |
||
Values can be raised to exceptions using raise(): |
Values can be raised to exceptions using raise(): |
||
<lang |
<syntaxhighlight lang="moo">raise(E_PERM);</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="moo">try |
||
this:foo(); |
this:foo(); |
||
except e (ANY) |
except e (ANY) |
||
this:bar(e); |
this:bar(e); |
||
endtry</ |
endtry</syntaxhighlight> |
||
MOO also has a finally statement: |
MOO also has a finally statement: |
||
< |
<syntaxhighlight lang="moo">try |
||
this:foo(); |
this:foo(); |
||
finally |
finally |
||
this:bar(); |
this:bar(); |
||
endtry</ |
endtry</syntaxhighlight> |
||
'''Shorthand''' |
'''Shorthand''' |
||
< |
<syntaxhighlight lang="moo">`this:foo()!ANY=>this:bar()';</syntaxhighlight> |
||
=={{header|Nanoquery}}== |
=={{header|Nanoquery}}== |
||
< |
<syntaxhighlight lang="nanoquery">try |
||
invalid "this statement will fail" |
invalid "this statement will fail" |
||
catch e |
catch e |
||
println "caught an exception" |
println "caught an exception" |
||
println e |
println e |
||
end try</ |
end try</syntaxhighlight> |
||
Throwing exceptions: |
Throwing exceptions: |
||
< |
<syntaxhighlight lang="nanoquery">throw new(Exception, "exception reason as string")</syntaxhighlight> |
||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
< |
<syntaxhighlight lang="nemerle">// define a new exception |
||
class MyException : Exception |
class MyException : Exception |
||
{ |
{ |
||
Line 1,912: | Line 1,912: | ||
finally { |
finally { |
||
... // code executes whether or not exception was thrown |
... // code executes whether or not exception was thrown |
||
}</ |
}</syntaxhighlight> |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
As <tt>NetRexx</tt> runs under the control of a JVM it has the same exception model as [[#Java|Java]]. |
As <tt>NetRexx</tt> runs under the control of a JVM it has the same exception model as [[#Java|Java]]. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols nobinary |
options replace format comments java crossref symbols nobinary |
||
Line 1,944: | Line 1,944: | ||
super('I resent that!') |
super('I resent that!') |
||
return |
return |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 1,952: | Line 1,952: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="nim">type SillyError = object of Exception</syntaxhighlight> |
||
'''Throwing an exception''' |
'''Throwing an exception''' |
||
< |
<syntaxhighlight lang="nim">proc spam() = |
||
raise newException(SillyError, "Some error")</ |
raise newException(SillyError, "Some error")</syntaxhighlight> |
||
'''Handling an exception''' |
'''Handling an exception''' |
||
< |
<syntaxhighlight lang="nim">try: |
||
spam() |
spam() |
||
except SillyError: |
except SillyError: |
||
Line 1,964: | Line 1,964: | ||
echo "Got another exception" |
echo "Got another exception" |
||
finally: |
finally: |
||
echo "Finally"</ |
echo "Finally"</syntaxhighlight> |
||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
Line 1,970: | Line 1,970: | ||
'''Defining exceptions'''<br> |
'''Defining exceptions'''<br> |
||
Exceptions can be any Objective-C object, though they are usually instances of <code>NSException</code>. You can create a subclass of NSException if necessary: |
Exceptions can be any Objective-C object, though they are usually instances of <code>NSException</code>. You can create a subclass of NSException if necessary: |
||
< |
<syntaxhighlight lang="objc">@interface MyException : NSException { |
||
//Put specific info in here |
//Put specific info in here |
||
} |
} |
||
@end</ |
@end</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="objc">- (void)foo { |
||
@throw [NSException exceptionWithName:@"TerribleException" |
@throw [NSException exceptionWithName:@"TerribleException" |
||
reason:@"OMGWTFBBQ111!1" userInfo:nil]; |
reason:@"OMGWTFBBQ111!1" userInfo:nil]; |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="objc">@try { |
||
[self foo]; |
[self foo]; |
||
} |
} |
||
Line 1,997: | Line 1,997: | ||
@finally { |
@finally { |
||
//This code is always executed after exiting the try block |
//This code is always executed after exiting the try block |
||
}</ |
}</syntaxhighlight> |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 2,003: | Line 2,003: | ||
'''Defining exceptions'''<br> |
'''Defining exceptions'''<br> |
||
Like constructors, exceptions may or may not have an argument: |
Like constructors, exceptions may or may not have an argument: |
||
< |
<syntaxhighlight lang="ocaml">exception My_Exception;; |
||
exception Another_Exception of string;;</ |
exception Another_Exception of string;;</syntaxhighlight> |
||
'''Throw exceptions'''<br> |
'''Throw exceptions'''<br> |
||
Throw exceptions with the "raise" function; the expression will match any type: |
Throw exceptions with the "raise" function; the expression will match any type: |
||
< |
<syntaxhighlight lang="ocaml">let foo x = |
||
match x with |
match x with |
||
1 -> raise My_Exception |
1 -> raise My_Exception |
||
| 2 -> raise (Another_Exception "hi mom") |
| 2 -> raise (Another_Exception "hi mom") |
||
| _ -> 5 |
| _ -> 5 |
||
;;</ |
;;</syntaxhighlight> |
||
'''Catching exceptions'''<br> |
'''Catching exceptions'''<br> |
||
The "with" syntax pattern-matches on the exception type and argument: |
The "with" syntax pattern-matches on the exception type and argument: |
||
< |
<syntaxhighlight lang="ocaml">try |
||
string_of_int (foo 2) |
string_of_int (foo 2) |
||
with |
with |
||
My_Exception -> "got my exception" |
My_Exception -> "got my exception" |
||
| Another_Exception s -> s |
| Another_Exception s -> s |
||
| _ -> "unknown exception"</ |
| _ -> "unknown exception"</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 2,030: | Line 2,030: | ||
It is also possible to create new exception classes (see Exception.of). |
It is also possible to create new exception classes (see Exception.of). |
||
< |
<syntaxhighlight lang="oforth">: iwillThrowAnException "A new exception" Exception throw ; |
||
: iwillCatch |
: iwillCatch |
||
Line 2,036: | Line 2,036: | ||
try: e [ iwillThrowAnException ] when: [ "Exception catched :" . e .cr ] |
try: e [ iwillThrowAnException ] when: [ "Exception catched :" . e .cr ] |
||
try: e [ 1 2 over last ] when: [ "Exception catched :" . e .cr ] |
try: e [ 1 2 over last ] when: [ "Exception catched :" . e .cr ] |
||
"Done" println ;</ |
"Done" println ;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,049: | Line 2,049: | ||
'''Throw exceptions'''<br> |
'''Throw exceptions'''<br> |
||
Any value can be thrown as an exception. Typically record values are used. |
Any value can be thrown as an exception. Typically record values are used. |
||
< |
<syntaxhighlight lang="oz">raise sillyError end |
||
raise slightlyLessSilly(data:42 reason:outOfMemory) end</ |
raise slightlyLessSilly(data:42 reason:outOfMemory) end</syntaxhighlight> |
||
By using a record value with a feature <code>debug</code> set to <code>unit</code> you can indicate that the exception shall have debug information (including a stack trace). |
By using a record value with a feature <code>debug</code> set to <code>unit</code> you can indicate that the exception shall have debug information (including a stack trace). |
||
< |
<syntaxhighlight lang="oz">try |
||
raise someError(debug:unit) end |
raise someError(debug:unit) end |
||
catch someError(debug:d(stack:ST ...)...) then |
catch someError(debug:d(stack:ST ...)...) then |
||
{Inspect ST} |
{Inspect ST} |
||
end</ |
end</syntaxhighlight> |
||
See also: [http://www.mozart-oz.org/documentation/base/exception.html Exceptions] in the Oz documentation. |
See also: [http://www.mozart-oz.org/documentation/base/exception.html Exceptions] in the Oz documentation. |
||
Line 2,064: | Line 2,064: | ||
'''Catching exceptions'''<br> |
'''Catching exceptions'''<br> |
||
Exception are caught with pattern matching. Ellipsis indicating additional optional fields are often useful here. |
Exception are caught with pattern matching. Ellipsis indicating additional optional fields are often useful here. |
||
< |
<syntaxhighlight lang="oz">try |
||
{Foo} |
{Foo} |
||
catch sillyError then |
catch sillyError then |
||
Line 2,074: | Line 2,074: | ||
finally |
finally |
||
{Fin} |
{Fin} |
||
end</ |
end</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
Line 2,105: | Line 2,105: | ||
|User-initiated error |
|User-initiated error |
||
|} |
|} |
||
< |
<syntaxhighlight lang="parigp">trap(/* specific error can be given here, or leave blank to catch all */, |
||
"caught" |
"caught" |
||
, |
, |
||
error("bad stuff") |
error("bad stuff") |
||
)</ |
)</syntaxhighlight> |
||
===Throwing errors in GP=== |
===Throwing errors in GP=== |
||
The only error that can be thrown in GP is user error: |
The only error that can be thrown in GP is user error: |
||
< |
<syntaxhighlight lang="parigp">error("Text of error here")</syntaxhighlight> |
||
===Throwing errors in PARI=== |
===Throwing errors in PARI=== |
||
Line 2,216: | Line 2,216: | ||
|} |
|} |
||
</div> |
</div> |
||
< |
<syntaxhighlight lang="c">pari_err(arither1, "functionName"); // Gives "*** functionName: not an integer argument in an arithmetic function"</syntaxhighlight> |
||
===Catching errors in PARI=== |
===Catching errors in PARI=== |
||
It is rare that this mechanism needs to be used in PARI, rather than standard [[#C|C]] methods, but the function <code>closure_trapgen</code> (similar to <code>closure_evalgen</code>) is available: |
It is rare that this mechanism needs to be used in PARI, rather than standard [[#C|C]] methods, but the function <code>closure_trapgen</code> (similar to <code>closure_evalgen</code>) is available: |
||
< |
<syntaxhighlight lang="c">GEN x = closure_trapgen(arither1, f); // Executes the function f, catching "not an integer argument in an arithmetic function" errors |
||
if (x == (GEN)1L) // Was there an error? |
if (x == (GEN)1L) // Was there an error? |
||
pari_printf("Don't do that!\n"); // Recover</ |
pari_printf("Don't do that!\n"); // Recover</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Line 2,232: | Line 2,232: | ||
Exceptions using the core [http://perldoc.perl.org/functions/eval.html eval] function: |
Exceptions using the core [http://perldoc.perl.org/functions/eval.html eval] function: |
||
< |
<syntaxhighlight lang="perl"># throw an exception |
||
die "Danger, danger, Will Robinson!"; |
die "Danger, danger, Will Robinson!"; |
||
Line 2,242: | Line 2,242: | ||
# rethrow |
# rethrow |
||
die $@;</ |
die $@;</syntaxhighlight> |
||
See http://perldoc.perl.org/perlvar.html#%24EVAL_ERROR for the meaning of the special variable <tt>$@</tt>. See http://search.cpan.org/dist/Error for advanced object based-exception handling. |
See http://perldoc.perl.org/perlvar.html#%24EVAL_ERROR for the meaning of the special variable <tt>$@</tt>. See http://search.cpan.org/dist/Error for advanced object based-exception handling. |
||
Line 2,249: | Line 2,249: | ||
The same using the [http://search.cpan.org/perldoc?Try::Tiny Try::Tiny] module: |
The same using the [http://search.cpan.org/perldoc?Try::Tiny Try::Tiny] module: |
||
< |
<syntaxhighlight lang="perl"># throw an exception |
||
die "Danger, danger, Will Robinson!";</ |
die "Danger, danger, Will Robinson!";</syntaxhighlight> |
||
< |
<syntaxhighlight lang="perl"># catch an exception and show it |
||
try { |
try { |
||
die "this could go wrong mightily"; |
die "this could go wrong mightily"; |
||
} catch { |
} catch { |
||
print; |
print; |
||
};</ |
};</syntaxhighlight> |
||
< |
<syntaxhighlight lang="perl"># rethrow (inside of catch) |
||
die $_;</ |
die $_;</syntaxhighlight> |
||
'''Other styles'''<br> |
'''Other styles'''<br> |
||
Line 2,269: | Line 2,269: | ||
'''Throwing exceptions'''<br> |
'''Throwing exceptions'''<br> |
||
You can throw any string (on it's own) or any integer, optionally with any (deeply nested) user_data that you like. |
You can throw any string (on it's own) or any integer, optionally with any (deeply nested) user_data that you like. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #008000;">"oh no"<span style="color: #0000FF;">)</span> |
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #008000;">"oh no"<span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">)</span> |
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">)</span> |
||
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">501<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #008000;">"she"<span style="color: #0000FF;">,<span style="color: #000000;">made<span style="color: #0000FF;">[<span style="color: #000000;">me<span style="color: #0000FF;">]<span style="color: #0000FF;">,<span style="color: #000000;">Do<span style="color: #0000FF;">(<span style="color: #000000;">it<span style="color: #0000FF;">)<span style="color: #0000FF;">}<span style="color: #0000FF;">) |
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">501<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #008000;">"she"<span style="color: #0000FF;">,<span style="color: #000000;">made<span style="color: #0000FF;">[<span style="color: #000000;">me<span style="color: #0000FF;">]<span style="color: #0000FF;">,<span style="color: #000000;">Do<span style="color: #0000FF;">(<span style="color: #000000;">it<span style="color: #0000FF;">)<span style="color: #0000FF;">}<span style="color: #0000FF;">) |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
'''Catching exceptions'''<br> |
'''Catching exceptions'''<br> |
||
There is one and only one non-optional catch clause per try statement. <br> |
There is one and only one non-optional catch clause per try statement. <br> |
||
The variable caught is a sequence, augmented with run-time diagnostics, with whatever was thrown in e[E_CODE] and/or e[E_USER]. |
The variable caught is a sequence, augmented with run-time diagnostics, with whatever was thrown in e[E_CODE] and/or e[E_USER]. |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #008080;">try</span> |
<span style="color: #008080;">try</span> |
||
<span style="color: #000000;">one_of<span style="color: #0000FF;">(<span style="color: #000000;">these<span style="color: #0000FF;">)</span> |
<span style="color: #000000;">one_of<span style="color: #0000FF;">(<span style="color: #000000;">these<span style="color: #0000FF;">)</span> |
||
Line 2,288: | Line 2,288: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">try |
<span style="color: #008080;">end</span> <span style="color: #008080;">try |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
An uncaught exception terminates the program in error, otherwise control resumes in the catch clause or after the end try, |
An uncaught exception terminates the program in error, otherwise control resumes in the catch clause or after the end try, |
||
Line 2,300: | Line 2,300: | ||
PHL does not support multiple catch-clauses. |
PHL does not support multiple catch-clauses. |
||
< |
<syntaxhighlight lang="phl">module exceptions; |
||
extern printf; |
extern printf; |
||
Line 2,322: | Line 2,322: | ||
} |
} |
||
return 0; |
return 0; |
||
]</ |
]</syntaxhighlight> |
||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
Line 2,331: | Line 2,331: | ||
'''Define exceptions''' |
'''Define exceptions''' |
||
< |
<syntaxhighlight lang="php">class MyException extends Exception |
||
{ |
{ |
||
// Custom exception attributes & methods |
// Custom exception attributes & methods |
||
}</ |
}</syntaxhighlight> |
||
'''Throwing exceptions''' |
'''Throwing exceptions''' |
||
< |
<syntaxhighlight lang="php">function throwsException() |
||
{ |
{ |
||
throw new Exception('Exception message'); |
throw new Exception('Exception message'); |
||
}</ |
}</syntaxhighlight> |
||
'''Catching Exceptions''' |
'''Catching Exceptions''' |
||
< |
<syntaxhighlight lang="php">try { |
||
throwsException(); |
throwsException(); |
||
} catch (Exception $e) { |
} catch (Exception $e) { |
||
echo 'Caught exception: ' . $e->getMessage(); |
echo 'Caught exception: ' . $e->getMessage(); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Line 2,355: | Line 2,355: | ||
'throw' will transfer control to a 'catch' environment |
'throw' will transfer control to a 'catch' environment |
||
that was set up with the given label. |
that was set up with the given label. |
||
< |
<syntaxhighlight lang="picolisp">(catch 'thisLabel # Catch this label |
||
(println 1) # Do some processing (print '1') |
(println 1) # Do some processing (print '1') |
||
(throw 'thisLabel 2) # Abort processing and return '2' |
(throw 'thisLabel 2) # Abort processing and return '2' |
||
(println 3) ) # This is never reached</ |
(println 3) ) # This is never reached</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>1 # '1' is printed |
<pre>1 # '1' is printed |
||
Line 2,364: | Line 2,364: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<lang> |
<syntaxhighlight lang="text"> |
||
/* Define a new exception, called "my_condition". */ |
/* Define a new exception, called "my_condition". */ |
||
on condition (my_condition) snap begin; |
on condition (my_condition) snap begin; |
||
Line 2,376: | Line 2,376: | ||
/* to be printed, and execution then resumes at the statement */ |
/* to be printed, and execution then resumes at the statement */ |
||
/* following the SIGNAL statement. */ |
/* following the SIGNAL statement. */ |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PL/pgSQL}}== |
=={{header|PL/pgSQL}}== |
||
'''Raise an exception''' |
'''Raise an exception''' |
||
<syntaxhighlight lang="sql"> |
|||
<lang SQL> |
|||
begin |
begin |
||
raise exception 'this is a generic user exception'; |
raise exception 'this is a generic user exception'; |
||
raise exception division_by_zero; |
raise exception division_by_zero; |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Handle an exception''' |
'''Handle an exception''' |
||
Hande division by zero and re-raising once caught other exception: |
Hande division by zero and re-raising once caught other exception: |
||
<syntaxhighlight lang="sql"> |
|||
<lang SQL> |
|||
create function special_division(p_num double precision, p_den double precision) returns text |
create function special_division(p_num double precision, p_den double precision) returns text |
||
as $body$ |
as $body$ |
||
Line 2,408: | Line 2,408: | ||
raise; |
raise; |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Pop11}}== |
=={{header|Pop11}}== |
||
Line 2,414: | Line 2,414: | ||
'''Throwing exceptions''' |
'''Throwing exceptions''' |
||
< |
<syntaxhighlight lang="pop11">define throw_exception(); |
||
throw([my_exception my_data]); |
throw([my_exception my_data]); |
||
enddefine;</ |
enddefine;</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="pop11">define main(); |
||
vars cargo; |
vars cargo; |
||
define catcher(); |
define catcher(); |
||
Line 2,429: | Line 2,429: | ||
enddefine; |
enddefine; |
||
main();</ |
main();</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
'''Throw an exception:''' |
'''Throw an exception:''' |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
throw "Any error message." |
throw "Any error message." |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,446: | Line 2,446: | ||
</pre> |
</pre> |
||
'''Throw a more specific exception:''' |
'''Throw a more specific exception:''' |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
throw [System.IO.FileNotFoundException] ".\temp.txt not found." |
throw [System.IO.FileNotFoundException] ".\temp.txt not found." |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,459: | Line 2,459: | ||
</pre> |
</pre> |
||
'''Using <code>try {} catch {}</code> is better for more complex error checking because you can test specific errors:''' |
'''Using <code>try {} catch {}</code> is better for more complex error checking because you can test specific errors:''' |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
try |
try |
||
{ |
{ |
||
Line 2,472: | Line 2,472: | ||
Write-Host "Other exception" |
Write-Host "Other exception" |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,483: | Line 2,483: | ||
</pre> |
</pre> |
||
'''Errors are objects like any other in PowerShell, so you may capture any detail of it:''' |
'''Errors are objects like any other in PowerShell, so you may capture any detail of it:''' |
||
<syntaxhighlight lang="powershell"> |
|||
<lang PowerShell> |
|||
$Error[0] | Get-Member |
$Error[0] | Get-Member |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,510: | Line 2,510: | ||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
< |
<syntaxhighlight lang="prolog">foo(X) :- |
||
\+ integer(X), |
\+ integer(X), |
||
throw(b('not even an int')). |
throw(b('not even an int')). |
||
Line 2,528: | Line 2,528: | ||
format('~w~n', Msg), |
format('~w~n', Msg), |
||
!. |
!. |
||
handle(X) :- throw(X).</ |
handle(X) :- throw(X).</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 2,549: | Line 2,549: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">Procedure ErrorHandler() |
||
MessageRequester("Exception test", "The following error happened: " + ErrorMessage()) |
MessageRequester("Exception test", "The following error happened: " + ErrorMessage()) |
||
EndProcedure |
EndProcedure |
||
Line 2,557: | Line 2,557: | ||
OnErrorCall(@ErrorHandler()) |
OnErrorCall(@ErrorHandler()) |
||
RaiseError(#PB_OnError_InvalidMemory) ;a custom error# can also be used here depending on the OS being compiled for</ |
RaiseError(#PB_OnError_InvalidMemory) ;a custom error# can also be used here depending on the OS being compiled for</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 2,563: | Line 2,563: | ||
'''Defining an exception''' |
'''Defining an exception''' |
||
< |
<syntaxhighlight lang="python">import exceptions |
||
class SillyError(exceptions.Exception): |
class SillyError(exceptions.Exception): |
||
def __init__(self,args=None): |
def __init__(self,args=None): |
||
self.args=args</ |
self.args=args</syntaxhighlight> |
||
Note: In most cases new exceptions are defined simply using the ''pass'' statement. For example: |
Note: In most cases new exceptions are defined simply using the ''pass'' statement. For example: |
||
< |
<syntaxhighlight lang="python">class MyInvalidArgument(ValueError): |
||
pass</ |
pass</syntaxhighlight> |
||
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). |
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). |
||
Line 2,579: | Line 2,579: | ||
Creating an exception using the default constructor of an exception class: |
Creating an exception using the default constructor of an exception class: |
||
< |
<syntaxhighlight lang="python">def spam(): |
||
raise SillyError # equivalent to raise SillyError()</ |
raise SillyError # equivalent to raise SillyError()</syntaxhighlight> |
||
{{works with|Python|2.5}} |
{{works with|Python|2.5}} |
||
Passing an argument to the constructor of an exception class: |
Passing an argument to the constructor of an exception class: |
||
< |
<syntaxhighlight lang="python">def spam(): |
||
raise SillyError, 'egg' # equivalent to raise SillyError('egg')</ |
raise SillyError, 'egg' # equivalent to raise SillyError('egg')</syntaxhighlight> |
||
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. |
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. |
||
{{works with|Python|2.x and 3.x}} |
{{works with|Python|2.x and 3.x}} |
||
< |
<syntaxhighlight lang="python">def spam(): |
||
raise SillyError('egg')</ |
raise SillyError('egg')</syntaxhighlight> |
||
'''Handling an exception'''<br> |
'''Handling an exception'''<br> |
||
Line 2,598: | Line 2,598: | ||
try-except-else-finally |
try-except-else-finally |
||
< |
<syntaxhighlight lang="python">try: |
||
foo() |
foo() |
||
except SillyError, se: |
except SillyError, se: |
||
Line 2,607: | Line 2,607: | ||
quux() |
quux() |
||
finally: |
finally: |
||
baz()</ |
baz()</syntaxhighlight> |
||
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). |
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). |
||
Line 2,614: | Line 2,614: | ||
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'' |
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'' |
||
< |
<syntaxhighlight lang="python">try: |
||
foo() |
foo() |
||
except SillyError as se: |
except SillyError as se: |
||
Line 2,623: | Line 2,623: | ||
quux() |
quux() |
||
finally: |
finally: |
||
baz()</ |
baz()</syntaxhighlight> |
||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
Line 2,635: | Line 2,635: | ||
When the condition is detected, <code>a</code>, or one of the words it invokes, will put a suitable message on the system ancillary stack called <code>message</code>, and invoke the word <code>bail</code>. |
When the condition is detected, <code>a</code>, or one of the words it invokes, will put a suitable message on the system ancillary stack called <code>message</code>, and invoke the word <code>bail</code>. |
||
< |
<syntaxhighlight lang="quackery"> <flag on stack indicating if condition detected> |
||
if [ $ "It all went pear shaped in 'a'." message put bail ]</ |
if [ $ "It all went pear shaped in 'a'." message put bail ]</syntaxhighlight> |
||
The one piece of necessary information about changes to the system state that Quackery cannot infer, even in "typical" usage, is the maximum number of items on the stack that may be removed or replaced during the execution of <code>a</code>. This needs to be specified by the programmer. (If the programmer is following conventions about stack comments, this could be gleaned from <code>a</code>'s stack comment, but Quackery steadfastly disregards all comments.) In this example, <code>a</code> consumes three stack items, so that is included in the code. How many it returns if there is no exception raised is not necessary information. |
The one piece of necessary information about changes to the system state that Quackery cannot infer, even in "typical" usage, is the maximum number of items on the stack that may be removed or replaced during the execution of <code>a</code>. This needs to be specified by the programmer. (If the programmer is following conventions about stack comments, this could be gleaned from <code>a</code>'s stack comment, but Quackery steadfastly disregards all comments.) In this example, <code>a</code> consumes three stack items, so that is included in the code. How many it returns if there is no exception raised is not necessary information. |
||
< |
<syntaxhighlight lang="quackery"> 3 backup a bailed if [ message take echo$ b ]</syntaxhighlight> |
||
<code>backup</code> makes a copy of the 3 topmost items on the stack and performs other necessary actions to ensure that the system state can be restored if <code>bail</code> is invoked during the execution of <code>a</code>. |
<code>backup</code> makes a copy of the 3 topmost items on the stack and performs other necessary actions to ensure that the system state can be restored if <code>bail</code> is invoked during the execution of <code>a</code>. |
||
Line 2,651: | Line 2,651: | ||
'''Define an exception''' |
'''Define an exception''' |
||
<syntaxhighlight lang="r"> |
|||
<lang r> |
|||
e <- simpleError("This is a simpleError") |
e <- simpleError("This is a simpleError") |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Raise an exception''' |
'''Raise an exception''' |
||
<syntaxhighlight lang="r"> |
|||
<lang r> |
|||
stop("An error has occured") |
stop("An error has occured") |
||
stop(e) #where e is a simpleError, as above |
stop(e) #where e is a simpleError, as above |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Handle an exception''' |
'''Handle an exception''' |
||
<syntaxhighlight lang="r"> |
|||
<lang r> |
|||
tryCatch( |
tryCatch( |
||
{ |
{ |
||
Line 2,676: | Line 2,676: | ||
finally = message("This is called whether or not an exception occured") |
finally = message("This is called whether or not an exception occured") |
||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 2,694: | Line 2,694: | ||
;; raise the exception |
;; raise the exception |
||
(raise (exn:my-exception "Hi!" (current-continuation-marks)))) |
(raise (exn:my-exception "Hi!" (current-continuation-marks)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 2,700: | Line 2,700: | ||
{{works with|rakudo|2015-09-10}} |
{{works with|rakudo|2015-09-10}} |
||
The Raku equivalent to Perl 5's eval {...} is try {...}. A try block by default has a CATCH block that handles all fatal exceptions by ignoring them. If you define a CATCH block within the try, it replaces the default CATCH. It also makes the try keyword redundant, because any block can function as a try block if you put a CATCH block within it. The inside of a CATCH functions as a switch statement on the current exception. |
The Raku equivalent to Perl 5's eval {...} is try {...}. A try block by default has a CATCH block that handles all fatal exceptions by ignoring them. If you define a CATCH block within the try, it replaces the default CATCH. It also makes the try keyword redundant, because any block can function as a try block if you put a CATCH block within it. The inside of a CATCH functions as a switch statement on the current exception. |
||
<lang |
<syntaxhighlight lang="raku" line>try { |
||
die "Help I'm dieing!"; |
die "Help I'm dieing!"; |
||
CATCH { |
CATCH { |
||
Line 2,716: | Line 2,716: | ||
CATCH { |
CATCH { |
||
default { note "No you're not."; say $_.Str; } |
default { note "No you're not."; say $_.Str; } |
||
}</ |
}</syntaxhighlight> |
||
<pre> |
<pre> |
||
Line 2,728: | Line 2,728: | ||
Rake comes with [http://design.raku.org/S04.html#Phasers phasers], that are called when certain conditions in the life of a program, routine or block are met. <tt>CATCH</tt> is one of them and works nicely together with <tt>LEAVE</tt> that is called even if an exception would force the current block to be left immediately. It's a nice place to put your cleanup code. |
Rake comes with [http://design.raku.org/S04.html#Phasers phasers], that are called when certain conditions in the life of a program, routine or block are met. <tt>CATCH</tt> is one of them and works nicely together with <tt>LEAVE</tt> that is called even if an exception would force the current block to be left immediately. It's a nice place to put your cleanup code. |
||
<lang |
<syntaxhighlight lang="raku" line>sub f(){ |
||
ENTER { note '1) f has been entered' } |
ENTER { note '1) f has been entered' } |
||
LEAVE { note '2) f has been left' } |
LEAVE { note '2) f has been left' } |
||
Line 2,740: | Line 2,740: | ||
CATCH { |
CATCH { |
||
when X::AdHoc { note q{6) no, I'm dead}; } |
when X::AdHoc { note q{6) no, I'm dead}; } |
||
}</ |
}</syntaxhighlight> |
||
<pre>1) f has been entered |
<pre>1) f has been entered |
||
Line 2,749: | Line 2,749: | ||
=={{header|Raven}}== |
=={{header|Raven}}== |
||
< |
<syntaxhighlight lang="raven">42 as custom_error |
||
define foo |
define foo |
||
Line 2,758: | Line 2,758: | ||
catch |
catch |
||
custom_error = |
custom_error = |
||
if 'oops' print</ |
if 'oops' print</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 2,765: | Line 2,765: | ||
This type of exception handling (in REXX) has its limitation |
This type of exception handling (in REXX) has its limitation |
||
(the label is local to the program, not external subroutines). |
(the label is local to the program, not external subroutines). |
||
< |
<syntaxhighlight lang="rexx">/*REXX program demonstrates handling an exception (negative #); catching is via a label.*/ |
||
do j=9 by -5 |
do j=9 by -5 |
||
say 'the square root of ' j " is " sqrt(j) |
say 'the square root of ' j " is " sqrt(j) |
||
Line 2,777: | Line 2,777: | ||
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g) * .5; end /*k*/ |
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g) * .5; end /*k*/ |
||
numeric digits d; return g/1 |
numeric digits d; return g/1 |
||
.sqrtNeg: say 'illegal SQRT argument (argument is negative):' x; exit 13</ |
.sqrtNeg: say 'illegal SQRT argument (argument is negative):' x; exit 13</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre> |
<pre> |
||
Line 2,786: | Line 2,786: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
Try |
Try |
||
see 1/0 |
see 1/0 |
||
Line 2,792: | Line 2,792: | ||
raise("Sorry we can't divide 1/0 + nl) |
raise("Sorry we can't divide 1/0 + nl) |
||
Done |
Done |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Line 2,798: | Line 2,798: | ||
'''Defining an exception''' |
'''Defining an exception''' |
||
< |
<syntaxhighlight lang="ruby"># define an exception |
||
class SillyError < Exception |
class SillyError < Exception |
||
end</ |
end</syntaxhighlight> |
||
SillyError is simply declared as a subclass of Exception. No over-riding is necessary. |
SillyError is simply declared as a subclass of Exception. No over-riding is necessary. |
||
< |
<syntaxhighlight lang="ruby">class MyInvalidArgument < ArgumentError |
||
end</ |
end</syntaxhighlight> |
||
MyInvalidArgument is a type of ArgumentError (a built-in class). 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. |
MyInvalidArgument is a type of ArgumentError (a built-in class). 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. |
||
Line 2,811: | Line 2,811: | ||
'''Handling an exception''' |
'''Handling an exception''' |
||
< |
<syntaxhighlight lang="ruby"> |
||
# raise (throw) an exception |
# raise (throw) an exception |
||
def spam |
def spam |
||
Line 2,822: | Line 2,822: | ||
rescue SillyError => se |
rescue SillyError => se |
||
puts se # writes 'egg' to stdout |
puts se # writes 'egg' to stdout |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ruby">begin |
||
foo |
foo |
||
rescue ArgumentError => e |
rescue ArgumentError => e |
||
Line 2,838: | Line 2,838: | ||
# always runs |
# always runs |
||
baz |
baz |
||
end</ |
end</syntaxhighlight> |
||
ArgumentError is a type of StandardError, but Ruby uses the first matching "rescue" clause. So we never "quack" for an ArgumentError, but we only "bar" for it. |
ArgumentError is a type of StandardError, but Ruby uses the first matching "rescue" clause. So we never "quack" for an ArgumentError, but we only "bar" for it. |
||
Line 2,844: | Line 2,844: | ||
The "rescue" clause is like the "catch" clause in other languages. The "ensure" clause is like the "finally" clause in other languages. |
The "rescue" clause is like the "catch" clause in other languages. The "ensure" clause is like the "finally" clause in other languages. |
||
< |
<syntaxhighlight lang="ruby"># short way to rescue any StandardError |
||
quotient = 1 / 0 rescue "sorry"</ |
quotient = 1 / 0 rescue "sorry"</syntaxhighlight> |
||
The short form "a rescue b" returns a, but if a raises a StandardError, then it returns b. (ZeroDivisionError is a subclass of StandardError.) |
The short form "a rescue b" returns a, but if a raises a StandardError, then it returns b. (ZeroDivisionError is a subclass of StandardError.) |
||
Line 2,853: | Line 2,853: | ||
Ruby has a separate exception-like system that is meant to be used to exit out of deep executions that are not errors. |
Ruby has a separate exception-like system that is meant to be used to exit out of deep executions that are not errors. |
||
< |
<syntaxhighlight lang="ruby">def foo |
||
throw :done |
throw :done |
||
end |
end |
||
Line 2,859: | Line 2,859: | ||
catch :done do |
catch :done do |
||
foo |
foo |
||
end</ |
end</syntaxhighlight> |
||
With Ruby 1.8, you can only "throw" and "catch" symbols. With Ruby 1.9, you can throw and catch any object. Like exceptions, the throw can be made from a function defined elsewhere from the catch block. |
With Ruby 1.8, you can only "throw" and "catch" symbols. With Ruby 1.9, you can throw and catch any object. Like exceptions, the throw can be made from a function defined elsewhere from the catch block. |
||
Line 2,869: | Line 2,869: | ||
It is illustrated by the code below: |
It is illustrated by the code below: |
||
< |
<syntaxhighlight lang="rust">// IO error is used here just as an example of an already existing |
||
// Error |
// Error |
||
use std::io::{Error, ErrorKind}; |
use std::io::{Error, ErrorKind}; |
||
Line 2,919: | Line 2,919: | ||
panicking_function(); |
panicking_function(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 2,929: | Line 2,929: | ||
In there are 3 main entries: object CheckingAccount, CheckingBlockingAccount and NotImplementedErrorTest to selective start this solution and demonstrate the working of exceptions and handling. |
In there are 3 main entries: object CheckingAccount, CheckingBlockingAccount and NotImplementedErrorTest to selective start this solution and demonstrate the working of exceptions and handling. |
||
< |
<syntaxhighlight lang="scala">//Defining exceptions |
||
class AccountBlockException extends Exception |
class AccountBlockException extends Exception |
||
class InsufficientFundsException(val amount: Double) extends Exception |
class InsufficientFundsException(val amount: Double) extends Exception |
||
Line 2,990: | Line 2,990: | ||
object NotImplementedErrorTest extends App { |
object NotImplementedErrorTest extends App { |
||
??? // Throws scala.NotImplementedError: an implementation is missing |
??? // Throws scala.NotImplementedError: an implementation is missing |
||
}</ |
}</syntaxhighlight> |
||
{{out}}Running entry point CheckingAccount |
{{out}}Running entry point CheckingAccount |
||
Line 3,011: | Line 3,011: | ||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
Exception handling can be created with any language supporting continuations, using as few primitves as possible, exception handling in Scheme can look like this. (But anyone wishing to continue using exceptions will abstract them into macros).< |
Exception handling can be created with any language supporting continuations, using as few primitves as possible, exception handling in Scheme can look like this. (But anyone wishing to continue using exceptions will abstract them into macros).<syntaxhighlight lang="scheme">(define (me-errors xx exception) |
||
(if (even? xx) |
(if (even? xx) |
||
xx |
xx |
||
Line 3,032: | Line 3,032: | ||
(all-ok))) |
(all-ok))) |
||
(display "oh my god it is ODD!")))</ |
(display "oh my god it is ODD!")))</syntaxhighlight> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
'''Raise an exception'''< |
'''Raise an exception'''<syntaxhighlight lang="seed7">const proc: foo is func |
||
begin |
begin |
||
raise RANGE_ERROR; |
raise RANGE_ERROR; |
||
end func;</ |
end func;</syntaxhighlight> |
||
'''Handle an exception''' |
'''Handle an exception''' |
||
< |
<syntaxhighlight lang="seed7">const proc: main is func |
||
begin |
begin |
||
block |
block |
||
Line 3,049: | Line 3,049: | ||
writeln("catched RANGE_ERROR"); |
writeln("catched RANGE_ERROR"); |
||
end block; |
end block; |
||
end func;</ |
end func;</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
An exception is thrown by the ''die'' keyword, which, if not caught, it terminates the program with an appropriate exit code. |
An exception is thrown by the ''die'' keyword, which, if not caught, it terminates the program with an appropriate exit code. |
||
< |
<syntaxhighlight lang="ruby">try { |
||
die "I'm dead!"; # throws an exception of type 'error' |
die "I'm dead!"; # throws an exception of type 'error' |
||
} |
} |
||
Line 3,063: | Line 3,063: | ||
say "I'm alive..."; |
say "I'm alive..."; |
||
die "Now I'm dead!"; # this line terminates the program |
die "Now I'm dead!"; # this line terminates the program |
||
say "Or am I?"; # Yes, you are!</ |
say "Or am I?"; # Yes, you are!</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,075: | Line 3,075: | ||
'''Handling Exceptions''' |
'''Handling Exceptions''' |
||
< |
<syntaxhighlight lang="slate">se@(SceneElement traits) doWithRestart: block |
||
[ |
[ |
||
block handlingCases: {Abort -> [| :_ | ^ Nil]} |
block handlingCases: {Abort -> [| :_ | ^ Nil]} |
||
].</ |
].</syntaxhighlight> |
||
'''Define Exceptions''' |
'''Define Exceptions''' |
||
< |
<syntaxhighlight lang="slate">conditions define: #Abort &parents: {Restart}. |
||
"An Abort is a Restart which exits the computation, unwinding the stack." |
"An Abort is a Restart which exits the computation, unwinding the stack." |
||
Line 3,099: | Line 3,099: | ||
[ |
[ |
||
c tryHandlers |
c tryHandlers |
||
].</ |
].</syntaxhighlight> |
||
'''Throwing Exceptions'''<br> |
'''Throwing Exceptions'''<br> |
||
{{lines too long|Slate}} |
{{lines too long|Slate}} |
||
< |
<syntaxhighlight lang="slate">(fileName endsWith: '.image') ifTrue: [error: 'Image filename specified where Slate source expected. Make sure you run slate with the -i flag to specify an image.'].</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
Throwing an Exception |
Throwing an Exception |
||
< |
<syntaxhighlight lang="smalltalk">"exec" "gst" "-f" "$0" "$0" "$*" |
||
"exit" |
"exit" |
||
Transcript show: 'Throwing yawp'; cr. |
Transcript show: 'Throwing yawp'; cr. |
||
self error: 'Yawp!'.</ |
self error: 'Yawp!'.</syntaxhighlight> |
||
< |
<syntaxhighlight lang="shell">$ ./yawp.st |
||
Throwing yawp |
Throwing yawp |
||
Object: nil error: Yawp! |
Object: nil error: Yawp! |
||
Line 3,120: | Line 3,120: | ||
Error(Exception)>>signal: (AnsiExcept.st:226) |
Error(Exception)>>signal: (AnsiExcept.st:226) |
||
UndefinedObject(Object)>>error: (AnsiExcept.st:1565) |
UndefinedObject(Object)>>error: (AnsiExcept.st:1565) |
||
UndefinedObject>>executeStatements (yawp.st:5)</ |
UndefinedObject>>executeStatements (yawp.st:5)</syntaxhighlight> |
||
Handling an Exception |
Handling an Exception |
||
< |
<syntaxhighlight lang="smalltalk">"exec" "gst" "-f" "$0" "$0" "$*" |
||
"exit" |
"exit" |
||
Line 3,132: | Line 3,132: | ||
] on: Error do: [ :e | |
] on: Error do: [ :e | |
||
Transcript show: 'Caught yawp'; cr. |
Transcript show: 'Caught yawp'; cr. |
||
].</ |
].</syntaxhighlight> |
||
< |
<syntaxhighlight lang="shell">$ ./yawp.st |
||
Throwing yawp |
Throwing yawp |
||
Caught yawp</ |
Caught yawp</syntaxhighlight> |
||
=={{header|SQL PL}}== |
=={{header|SQL PL}}== |
||
{{works with|Db2 LUW}} |
{{works with|Db2 LUW}} |
||
With SQL PL: |
With SQL PL: |
||
< |
<syntaxhighlight lang="sql pl"> |
||
--#SET TERMINATOR @ |
--#SET TERMINATOR @ |
||
Line 3,158: | Line 3,158: | ||
END IF; |
END IF; |
||
END @ |
END @ |
||
</syntaxhighlight> |
|||
</lang> |
|||
The next example just raise an exception, does not wrap a raised one. |
The next example just raise an exception, does not wrap a raised one. |
||
< |
<syntaxhighlight lang="sql pl"> |
||
BEGIN |
BEGIN |
||
SIGNAL SQLSTATE '75002' |
SIGNAL SQLSTATE '75002' |
||
SET MESSAGE_TEXT = 'Customer number is not known'; |
SET MESSAGE_TEXT = 'Customer number is not known'; |
||
END @ |
END @ |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 3,190: | Line 3,190: | ||
'''Define Exceptions''' |
'''Define Exceptions''' |
||
< |
<syntaxhighlight lang="sml">exception MyException; |
||
exception MyDataException of int; (* can be any first-class type, not just int *)</ |
exception MyDataException of int; (* can be any first-class type, not just int *)</syntaxhighlight> |
||
'''Throw Exceptions''' |
'''Throw Exceptions''' |
||
< |
<syntaxhighlight lang="sml">fun f() = raise MyException; |
||
fun g() = raise MyDataException 22;</ |
fun g() = raise MyDataException 22;</syntaxhighlight> |
||
'''Catch Exceptions''' |
'''Catch Exceptions''' |
||
< |
<syntaxhighlight lang="sml">val x = f() handle MyException => 22; |
||
val y = f() handle MyDataException x => x;</ |
val y = f() handle MyDataException x => x;</syntaxhighlight> |
||
=={{header|Stata}}== |
=={{header|Stata}}== |
||
Line 3,210: | Line 3,210: | ||
Example of usage: |
Example of usage: |
||
< |
<syntaxhighlight lang="stata">capture confirm file titanium.dta |
||
if _rc { |
if _rc { |
||
if _rc==601 { |
if _rc==601 { |
||
Line 3,219: | Line 3,219: | ||
display "there was an error with return code " _rc |
display "there was an error with return code " _rc |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Similarly, Mata has functions '''[http://www.stata.com/help.cgi?mf_error error]''' and '''[http://www.stata.com/help.cgi?mf_exit exit]''' to terminate execution, as well as '''[http://www.stata.com/help.cgi?mf_assert assert]''' and '''asserteq'''. |
Similarly, Mata has functions '''[http://www.stata.com/help.cgi?mf_error error]''' and '''[http://www.stata.com/help.cgi?mf_exit exit]''' to terminate execution, as well as '''[http://www.stata.com/help.cgi?mf_assert assert]''' and '''asserteq'''. |
||
Line 3,227: | Line 3,227: | ||
'''Defining exceptions'''<br /> |
'''Defining exceptions'''<br /> |
||
Exceptions can be of any type that conforms to the <code>ErrorType</code> protocol. |
Exceptions can be of any type that conforms to the <code>ErrorType</code> protocol. |
||
< |
<syntaxhighlight lang="swift">enum MyException : ErrorType { |
||
case TerribleException |
case TerribleException |
||
}</ |
}</syntaxhighlight> |
||
'''Throw exceptions'''<br /> |
'''Throw exceptions'''<br /> |
||
A function that throws an exception must be explicitly declared so: |
A function that throws an exception must be explicitly declared so: |
||
< |
<syntaxhighlight lang="swift">func foo() throws { |
||
throw MyException.TerribleException |
throw MyException.TerribleException |
||
}</ |
}</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="swift">do { |
||
try foo() |
try foo() |
||
} catch MyException.TerribleException { // this can be any pattern |
} catch MyException.TerribleException { // this can be any pattern |
||
Line 3,244: | Line 3,244: | ||
} catch { |
} catch { |
||
//Catch any exception |
//Catch any exception |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.5 |
||
# Throw |
# Throw |
||
Line 3,261: | Line 3,261: | ||
} |
} |
||
f</ |
f</syntaxhighlight> |
||
This creates the stack trace |
This creates the stack trace |
||
<pre>error message for stack trace |
<pre>error message for stack trace |
||
Line 3,272: | Line 3,272: | ||
=={{header|Transd}}== |
=={{header|Transd}}== |
||
< |
<syntaxhighlight lang="scheme">#lang transd |
||
mainModule : { |
mainModule : { |
||
Line 3,296: | Line 3,296: | ||
_start: (lambda (func1)) |
_start: (lambda (func1)) |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
OUTPUT: |
OUTPUT: |
||
--------------- |
--------------- |
||
Line 3,318: | Line 3,318: | ||
In the main @(collect) clause, we have a try protect block in which we collect three different cases of primate. For each one, we throw an exception with the primate type symbol, and its name. This is caught in the catch clause as the argument "name". The catch clause performs another pattern match, @kind @name. This match is being applied to exactly the same line of data for which the exception was thrown (backtracking!). Therefore the @kind variable will collect the primate type. However @name already has a binding since it is the argument of the catch. Since it has a value already, that value has to match what is in the data. Of course, it does since it was derived from that data. The data and the variable unify against each other. |
In the main @(collect) clause, we have a try protect block in which we collect three different cases of primate. For each one, we throw an exception with the primate type symbol, and its name. This is caught in the catch clause as the argument "name". The catch clause performs another pattern match, @kind @name. This match is being applied to exactly the same line of data for which the exception was thrown (backtracking!). Therefore the @kind variable will collect the primate type. However @name already has a binding since it is the argument of the catch. Since it has a value already, that value has to match what is in the data. Of course, it does since it was derived from that data. The data and the variable unify against each other. |
||
< |
<syntaxhighlight lang="txr">@(defex gorilla ape primate) |
||
@(defex monkey primate) |
@(defex monkey primate) |
||
@(defex human primate) |
@(defex human primate) |
||
Line 3,339: | Line 3,339: | ||
@(end)@#output |
@(end)@#output |
||
@(end)@#try |
@(end)@#try |
||
@(end)@#collect</ |
@(end)@#collect</syntaxhighlight> |
||
Sample interactive run. Here the input is typed into standard input from the tty. The output is interleaved with the input, since TXR doesn't reads ahead only as much data as it needs. |
Sample interactive run. Here the input is typed into standard input from the tty. The output is interleaved with the input, since TXR doesn't reads ahead only as much data as it needs. |
||
Line 3,355: | Line 3,355: | ||
=={{header|Ursa}}== |
=={{header|Ursa}}== |
||
Catching exceptions: |
Catching exceptions: |
||
< |
<syntaxhighlight lang="ursa">try |
||
invalid "this statement will fail" |
invalid "this statement will fail" |
||
catch syntaxerror |
catch syntaxerror |
||
# console.err is optional here |
# console.err is optional here |
||
out "caught an exception" endl console.err |
out "caught an exception" endl console.err |
||
end try</ |
end try</syntaxhighlight> |
||
Throwing exceptions: |
Throwing exceptions: |
||
< |
<syntaxhighlight lang="ursa">throw (new ursa.exceptions.exception)</syntaxhighlight> |
||
=={{header|Ursala}}== |
=={{header|Ursala}}== |
||
Line 3,370: | Line 3,370: | ||
raises an exception with the diagnostic message 'epic fail'. |
raises an exception with the diagnostic message 'epic fail'. |
||
(The diagnostic message can also be made to depend on the input.) |
(The diagnostic message can also be made to depend on the input.) |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
thrower = ~&?/'success'! -[epic fail]-!% |
thrower = ~&?/'success'! -[epic fail]-!% |
||
catcher = guard(thrower,---[someone failed]-)</ |
catcher = guard(thrower,---[someone failed]-)</syntaxhighlight> |
||
If the exception is not caught, the program terminates immediately and |
If the exception is not caught, the program terminates immediately and |
||
Line 3,387: | Line 3,387: | ||
throwing exceptions |
throwing exceptions |
||
< |
<syntaxhighlight lang="v">[myproc |
||
['new error' 1 2 3] throw |
['new error' 1 2 3] throw |
||
'should not come here' puts |
'should not come here' puts |
||
].</ |
].</syntaxhighlight> |
||
catching them |
catching them |
||
< |
<syntaxhighlight lang="v">[myproc] [puts] catch |
||
=[new error 1 2 3]</ |
=[new error 1 2 3]</syntaxhighlight> |
||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
Line 3,404: | Line 3,404: | ||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="vb">Sub foo1() |
||
err.raise(vbObjectError + 1050) |
err.raise(vbObjectError + 1050) |
||
End Sub |
End Sub |
||
Line 3,411: | Line 3,411: | ||
Error vbObjectError + 1051 |
Error vbObjectError + 1051 |
||
End Sub |
End Sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="vb">Sub bar1() |
||
'by convention, a simple handler |
'by convention, a simple handler |
||
On Error GoTo catch |
On Error GoTo catch |
||
Line 3,459: | Line 3,459: | ||
end_try: |
end_try: |
||
'by convention, often just a drop through from the catch block |
'by convention, often just a drop through from the catch block |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
'''Defining exceptions''' |
'''Defining exceptions''' |
||
< |
<syntaxhighlight lang="vbnet">Class MyException |
||
Inherits Exception |
Inherits Exception |
||
'data with info about exception |
'data with info about exception |
||
End Class</ |
End Class</syntaxhighlight> |
||
'''Throw exceptions''' |
'''Throw exceptions''' |
||
< |
<syntaxhighlight lang="vbnet">Sub foo() |
||
Throw New MyException |
Throw New MyException |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
'''Catching exceptions''' |
'''Catching exceptions''' |
||
< |
<syntaxhighlight lang="vbnet">Sub bar() |
||
Try |
Try |
||
foo() |
foo() |
||
Line 3,488: | Line 3,488: | ||
'code here occurs whether or not there was an exception |
'code here occurs whether or not there was an exception |
||
End Try |
End Try |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 3,496: | Line 3,496: | ||
Here's an example of all this. |
Here's an example of all this. |
||
< |
<syntaxhighlight lang="ecmascript">var intDiv = Fn.new { |a, b| |
||
if (!(a is Num && a.isInteger) || !(b is Num && b.isInteger)) Fiber.abort("Invalid argument(s).") |
if (!(a is Num && a.isInteger) || !(b is Num && b.isInteger)) Fiber.abort("Invalid argument(s).") |
||
if (b == 0) Fiber.abort("Division by zero error.") |
if (b == 0) Fiber.abort("Division by zero error.") |
||
Line 3,513: | Line 3,513: | ||
System.print("%(e[0]) / %(e[1]) = %(d)") |
System.print("%(e[0]) / %(e[1]) = %(d)") |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,525: | Line 3,525: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
< |
<syntaxhighlight lang="zkl">try{ throw(Exception.BadDay) } |
||
catch { println(__exception," was thrown") } |
catch { println(__exception," was thrown") } |
||
fallthrough { println("No exception was thrown") } |
fallthrough { println("No exception was thrown") } |
||
println("OK");</ |
println("OK");</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,535: | Line 3,535: | ||
</pre> |
</pre> |
||
If you want "finally" functionality, use onExit or onExitBlock: |
If you want "finally" functionality, use onExit or onExitBlock: |
||
< |
<syntaxhighlight lang="zkl">fcn f(b){ |
||
try{ |
try{ |
||
onExitBlock("Exit code".println); |
onExitBlock("Exit code".println); |
||
Line 3,545: | Line 3,545: | ||
} |
} |
||
f(False); println("--------"); |
f(False); println("--------"); |
||
f(True);</ |
f(True);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,558: | Line 3,558: | ||
=={{header|Zig}}== |
=={{header|Zig}}== |
||
< |
<syntaxhighlight lang="zig">const std = @import("std"); |
||
// To replace exceptions, Zig has error enums to handle error states. |
// To replace exceptions, Zig has error enums to handle error states. |
||
Line 3,576: | Line 3,576: | ||
return err; |
return err; |
||
}; |
}; |
||
}</ |
}</syntaxhighlight> |
Revision as of 10:41, 27 August 2022
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.
- Related task
11l
T SillyError
String message
F (message)
.message = message
X.try
X SillyError(‘egg’)
X.catch SillyError se
print(se.message)
8086 Assembly
An exception in assembly language is often little more than just a conditional branch. Most MS-DOS system calls return the carry flag set if an error occured, and the error code will be returned in AX
. This lets you write your own exception handler that prints a relevant error message to the screen. You'll need to read the documentation to know what each error code means.
;syscall for creating a new file.
mov dx,offset filename
mov cx,0
mov ah,5Bh
int 21h
;if error occurs, will return carry set and error code in ax
;Error code 03h = path not found
;Error code 04h = Too many open files
;Error code 05h = Access denied
;Error code 50h = File already exists
jnc noError ;continue with program
cmp ax,03h
je PathNotFoundError ;unimplemented exception handler
cmp ax,04h
je TooManyOpenFilesError
cmp ax,05h
je AccessDeniedError
cmp ax,50h
je FileAlreadyExistsError
noError:
Ada
Define an exception
Foo_Error : exception;
Raise an exception
procedure Foo is
begin
raise Foo_Error;
end Foo;
Re-raising once caught exception:
...
exception
when Foo_Error =>
if ... then -- Alas, cannot handle it here,
raise; -- continue propagation of
end if;
Handle an exception
procedure Call_Foo is
begin
Foo;
exception
when Foo_Error =>
... -- do something
when others =>
... -- this catches all other exceptions
end Call_Foo;
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:
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;
Aikido
Aikido provides try
, catch
and throw
statements.
Catching exceptions
There is one catch
clause per try
statement. The variable caught is whatever is thrown. It does not have to be a particular type, although there is a System.Exception
class defined for system exceptions.
try {
var lines = readfile ("input.txt")
process (lines)
} catch (e) {
do_somthing(e)
}
Throwing exceptions
You can throw any value.
if (error) {
throw "Error"
}
if (something) {
throw new MyException (errorcode, a, b)
}
Aime
Simple Exception Throwing
void
throwing(void)
{
o_text("throwing...\n");
error("now!");
}
void
catching(void)
{
o_text("ready to catch\n");
if (trap(throwing)) {
o_text("caught!\n");
} else {
# nothing was thrown
}
}
integer
main(void)
{
catching();
return 0;
}
- Output:
ready to catch throwing... aime: tmp/et: 5: now! caught!
Exception Types
void
ft(integer a, text &s)
{
if (a & 1) {
s = "odd";
error("bad number");
} elif (a & a - 1) {
s = "not a power of two";
error("bad number");
}
}
void
fc(integer a)
{
text e;
if (trap(ft, a, e)) {
v_text("exception of type `");
v_text(e);
v_text("' thrown for ");
v_integer(a);
v_newline();
} else {
v_text("no exception thrown for ");
v_integer(a);
v_newline();
}
}
integer
main(void)
{
fc(5);
fc(6);
fc(8);
return 0;
}
- Output:
aime: tmp/et1: 6: bad number exception of type `odd' thrown for 5 aime: tmp/et1: 9: bad number exception of type `not a power of two' thrown for 6 no exception thrown for 8
ALGOL 68
Typically: In the Algol68 transput an attempt is first made to "mend" an "event" on an object. However: After a mend has failed, the event may be "sent" (via a GO TO) then "caught" by in an outside scope.
The "GOST 27975-88 Programming language ALGOL 68 extended" Soviet standard - (Язык программирования АЛГОЛ 68 расширенный (PDF)) had the addition mechanisms, e.g.: on, exception & raise.
File: prelude/event_base(obj).a68
COMMENT
Define an general event handling mechanism on MODE OBJ:
* try to parallel pythons exception handling flexibility
END COMMENT
COMMENT
REQUIRES:
MODE OBJ # These can be a UNION of REF types #
OP OBJIS
PROVIDES:
OP ON, RAISE, RESET
PROC obj on, obj raise, obj reset
END COMMENT
# define object related to OBJ EVENTS #
MODE
RAISEOBJ = PROC(OBJ)VOID, RAWMENDOBJ = PROC(OBJ)BOOL,
MENDOBJ = UNION(RAWMENDOBJ, PROC VOID), # Generalise: Allow PROC VOID (a GOTO) as a short hand #
NEWSCOPEOBJ = STRUCT(REF NEWSCOPEOBJ up, FLEXOBJ obj flex, FLEXEVENTOBJ event flex, MENDOBJ mended),
SCOPEOBJ = REF NEWSCOPEOBJ;
MODE FLEXOBJ=FLEX[0]OBJ;
# Provide an INIT to convert a GO TO to a MEND ... useful for direct aborts #
OP INITMENDOBJ = (PROC VOID go to)MENDOBJ: (go to; SKIP);
SCOPEOBJ obj scope end = NIL;
SCOPEOBJ obj scope begin := obj scope end; # INITialise stack #
OBJ obj any = EMPTY;
EVENTOBJ obj event any = NIL;
# Some crude Singly Linked-List manipulations of the scopes, aka stack ... #
# An event/mended can be shared for all OBJ of the same type: #
PRIO INITAB = 1, +=: = 1;
OP INITAB = (SCOPEOBJ lhs, MENDOBJ obj mend)SCOPEOBJ:
lhs := (obj scope end, obj any, obj event any, obj mend);
OP INITSCOPE = (MENDOBJ obj mend)SCOPEOBJ: HEAP NEWSCOPEOBJ INITAB obj mend;
OP +=: = (SCOPEOBJ item, REF SCOPEOBJ rhs)SCOPEOBJ: ( up OF item := rhs; rhs := item );
OP +=: = (MENDOBJ mend, REF SCOPEOBJ rhs)SCOPEOBJ: INITSCOPE mend +=: rhs;
#OP -=: = (REF SCOPEOBJ scope)SCOPEOBJ: scope := up OF scope;#
COMMENT Restore the prio event scope: ~ END COMMENT
PROC obj reset = (SCOPEOBJ up scope)VOID: obj scope begin := up scope;
MENDOBJ obj unmendable = (OBJ obj)BOOL: FALSE;
MODE NEWEVENTOBJ = STRUCT( # the is simple a typed place holder #
SCOPEOBJ scope,
STRING description,
PROC (OBJ #obj#, MENDOBJ #obj mend#)SCOPEOBJ on,
PROC (OBJ #obj#, STRING #msg#)VOID raise
), EVENTOBJ = REF NEWEVENTOBJ;
MODE FLEXEVENTOBJ = FLEX[0]EVENTOBJ;
COMMENT Define how to catch an event:
obj - IF obj IS NIL then mend event on all OBJects
obj mend - PROC to call to repair the object
return the prior event scope
END COMMENT
PROC obj on = (FLEXOBJ obj flex, FLEXEVENTOBJ event flex, MENDOBJ mend)SCOPEOBJ: (
mend +=: obj scope begin;
IF obj any ISNTIN obj flex THEN obj flex OF obj scope begin := obj flex FI;
IF obj event any ISNTIN event flex THEN event flex OF obj scope begin := event flex FI;
up OF obj scope begin
);
PRIO OBJIS = 4, OBJISNT = 4; # pick the same PRIOrity as EQ and NE #
OP OBJISNT = (OBJ a,b)BOOL: NOT(a OBJIS b);
PRIO ISIN = 4, ISNTIN = 4;
OP ISNTIN = (OBJ obj, FLEXOBJ obj flex)BOOL: (
BOOL isnt in := FALSE;
FOR i TO UPB obj flex WHILE isnt in := obj OBJISNT obj flex[i] DO SKIP OD;
isnt in
);
OP ISIN = (OBJ obj, FLEXOBJ obj flex)BOOL: NOT(obj ISNTIN obj flex);
OP ISNTIN = (EVENTOBJ event, FLEXEVENTOBJ event flex)BOOL: (
BOOL isnt in := TRUE;
FOR i TO UPB event flex WHILE isnt in := event ISNT event flex[i] DO SKIP OD;
isnt in
);
OP ISIN = (EVENTOBJ event, FLEXEVENTOBJ event flex)BOOL: NOT(event ISNTIN event flex);
COMMENT Define how to raise an event, once it is raised try and mend it:
if all else fails produce an error message and stop
END COMMENT
PROC obj raise = (OBJ obj, EVENTOBJ event, STRING msg)VOID:(
SCOPEOBJ this scope := obj scope begin;
# until mended this event should cascade through scope event handlers/members #
FOR i WHILE this scope ISNT SCOPEOBJ(obj scope end) DO
IF (obj any ISIN obj flex OF this scope OR obj ISIN obj flex OF this scope ) AND
(obj event any ISIN event flex OF this scope OR event ISIN event flex OF this scope)
THEN
CASE mended OF this scope IN
(RAWMENDOBJ mend):IF mend(obj) THEN break mended FI,
(PROC VOID go to): (go to; stop)
OUT put(stand error, "undefined: raise stop"); stop
ESAC
FI;
this scope := up OF this scope
OD;
put(stand error, ("OBJ event: ",msg)); stop; FALSE
EXIT
break mended: TRUE
);
CO define ON and some useful(?) RAISE OPs CO
PRIO ON = 1, RAISE = 1;
OP ON = (MENDOBJ mend, EVENTOBJ event)SCOPEOBJ: obj on(obj any, event, mend),
RAISE = (OBJ obj, EVENTOBJ event)VOID: obj raise(obj, event, "unnamed event"),
RAISE = (OBJ obj, MENDOBJ mend)VOID: ( mend ON obj event any; obj RAISE obj event any),
RAISE = (EVENTOBJ event)VOID: obj raise(obj any, event, "unnamed event"),
RAISE = (MENDOBJ mend)VOID: ( mend ON obj event any; RAISE obj event any),
RAISE = (STRING msg, EVENTOBJ event)VOID: obj raise(obj any, event, msg);
OP (SCOPEOBJ #up scope#)VOID RESET = obj reset;
SKIP
File: test/event.a68
#!/usr/bin/a68g --script #
MODE OBJ=UNION(REF INT, REF REAL, REF STRING,# etc # VOID);
OP OBJIS = (OBJ a,b)BOOL: # Are a and b at the same address? #
CASE a IN # Ironically Algol68's STRONG typing means we cannot simply compare addresses #
(REF INT a): a IS (b|(REF INT b):b|NIL),
(REF REAL a): a IS (b|(REF REAL b):b|NIL),
(REF STRING a): a IS (b|(REF STRING b):b|NIL)
OUT FALSE
ESAC;
PR READ "prelude/event_base(obj).a68" PR;
NEWEVENTOBJ obj eventa := SKIP;
NEWEVENTOBJ obj eventb := SKIP;
NEWEVENTOBJ user defined exception := SKIP;
# An event can be continued "mended" or break "unmended" #
PROC found sum sqs continue = (OBJ obj)BOOL: ( print("."); TRUE); # mended #
PROC found sum sqs break = (OBJ obj)BOOL: (found sq sum sqs; FALSE); # unmended #
INT sum sqs:=0;
REAL x:=111, y:=222, z:=333;
SCOPEOBJ obj scope reset := obj on((sum sqs, x,y,z), (obj eventa,obj eventb), VOID:found sq sum sqs);
# An event handler specific to the specific object instance: #
#SCOPEOBJ obj scope reset := obj on eventb(sum sqs, VOID:found sq sum sqs);#
# Or... An "obj any" event handler: #
# SCOPEOBJ obj scope reset := found sum sqs break ON obj eventb; #
# Raise the "event eventb" on an object: #
FOR i DO
sum sqs +:= i*i;
IF sum sqs = 70*70 THEN # 1st try to use an instance specific mend on the object #
obj raise(sum sqs, obj eventb, "Found a sq sum of sqs") FI; # OR ... #
IF sum sqs = 70*70 THEN "Found a sq sum of sqs" RAISE obj eventb FI; # OR ... #
IF sum sqs = 70*70 THEN RAISE found sum sqs break FI # simplest #
OD;
RESET obj scope reset # need to manually reset back to prior handlers #
# Catch "event eventb": #
EXIT found sq sum sqs:
print(("sum sqs:",sum sqs, new line)); # event eventb caught code here ... #
RESET obj scope reset;
"finally: raise the base unmendable event" RAISE obj eventb
- Output:
sum sqs: +4900 OBJ event: finally: raise the base unmendable event
Standard Prelude "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 encountered during transput
- on page end - if the end of a page was encountered during transput
- on physical file end - if the end of physical media was encountered 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 prelude routine to reposition the FILE and rectify the detected event, e.g.:
- 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 un-handled, and the standard prelude 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.
- See also
- StackOverflow: What language was the first to implement exception handling?
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
AutoHotkey
True exceptions
In AutoHotkey_L Try, Catch, and Throw are available to handle exceptions.
From the Throw documentation:
try
BadlyCodedFunc()
catch e
MsgBox % "Error in " e.What ", which was called at line " e.Line
BadlyCodedFunc() {
throw Exception("Fail", -1)
}
ErrorLevel-based exceptions
In AutoHotkey_Basic, the only option for error-handling is using ErrorLevel
foo()
If ErrorLevel
Msgbox calling foo failed with: %ErrorLevel%
foo()
{
If success
Return
Else
ErrorLevel = foo_error
Return
}
BBC BASIC
ON ERROR PROCerror(ERR, REPORT$) : END
ERROR 100, "User-generated exception"
END
DEF PROCerror(er%, rpt$)
PRINT "Exception occurred"
PRINT "Error number was " ; er%
PRINT "Error string was " rpt$
ENDPROC
Output:
Exception occurred Error number was 100 Error string was User-generated exception
blz
try
1 / 0 # Throw an exception
print("unreachable code")
catch
print("An error occured!")
end
Bracmat
After completed evaluation, each Bracmat expression not only has a value, but also a success or failure status attached to it. Pattern matching expressions are the most common expressions to test some condition, but also other expressions can obtain a status different from 'success'. Here are some situations where an expression fails:
- pattern matching fails if the pattern does not match the subject
- reading the contents of a file fails if the file cannot be opened for reading or if the file has not the expected format
- retrieving a value bound to a symbol that has no value bound to it fails
- accessing an object member that does not exist fails
- division by zero fails
- an operation headed by the 'and then' operator
&
fails if either its left hand side or its right hand side fails - an operation headed by the 'or else' operator
|
fails if both its left hand side and its right hand side fail
Rather than writing statements delimited by ;
characters, which do not have usefull succes/failure states, you write
a Bracmat program with 'and then' and 'or else' as connectives between expressions. A Bracmat program therefore needs only consist
of a single statement. In many cases a series of expressions connected with the 'and then' operator is meant to succeed,
evaluating each expression in turn with success. In an exceptional case, however, such as a file that cannot be opened, the series
is interrupted and control can be taken over by an outer 'or else' control structure that evaluates its right hand side.
To 'throw and exception' you can use the always failing expression ~
. In the example, the ~
ensures that
the call to the contemplate
function is never attempted if something went wrong with reading the files. This failure
percolates further up, so calling the function MyFunction
fails as well, making the whole program fail.
( ( MyFunction
= someText XMLstuff
. ( get$!arg:?someText
& get$("CorporateData.xml",X,ML):?XMLstuff
| out
$ ( str
$ ( "Something went wrong when reading your file \""
!arg
"\". Or was it the Corporate Data? Hard to say. Anyhow, now I throw you out."
)
)
& ~
)
& contemplate$(!someText,!XMLstuff)
)
& MyFunction$"Tralula.txt"
);
If you copy/paste this code to the Bracmat prompt without the statement delimiter ;
, you will see an 'F' after the output, indicating that your input failed to
evaluate successfully.
Something went wrong when reading your file "Tralula.txt". Or was it the Corporate Data? Hard to say. Anyhow, now I throw you out. F
C
The setjmp()/longjmp() functions in the C standard library header <setjmp.h> are typically used for exception handling.
try-catch
#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 */
/* note: if this "default" section is not included, that would be equivalent to a blank "default" section */
/* i.e. any exception not caught above would be caught and ignored */
/* there is no way to "let the exception through" */
}
}
With multi-thread support and nested exceptions
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
enum exceptions {
EXCEPTION_1 = 1,
EXCEPTION_2,
EXCEPTION_3
};
#define throw(exception) do { \
if (exp) \
longjmp(*exp, exception); \
printf("uncaught exception %d\n", exception); \
exit(exception); \
} while (0)
#define try(block, catch_block) \
{ \
jmp_buf *exception_outer = exp; \
jmp_buf exception_inner; \
exp = &exception_inner; \
int exception = setjmp(*exp); \
if (!exception) { \
do block while(0); \
exp = exception_outer; \
} else { \
exp = exception_outer; \
switch(exception) { \
catch_block \
default: \
throw(exception); \
} \
} \
}
#define catch(exception, block) \
case exception: do block while (0); break;
#define throws jmp_buf* exp
// define a throwing function
void g(throws) {
printf("g !\n");
throw(EXCEPTION_1);
printf("shouldnt b here\n");
}
void h(throws, int a)
{
printf("h %d!\n", a);
throw(EXCEPTION_2);
}
void f(throws) {
try({
g(exp); // call g with intention to catch exceptions
},
catch(EXCEPTION_1, {
printf("exception 1\n");
h(exp, 50); // will throw exception 2 inside this catch block
}))
}
int main(int argc, char* argv[])
{
throws = NULL; // define exception stack base
try({
f(exp);
},
catch(EXCEPTION_2, {
printf("exception 2\n");
})
catch(EXCEPTION_3, {
printf("exception 3\n");
}))
h(exp, 60); // will result in "uncaught exception"
return 0;
}
Now all we need to do is add a finally block :) hint: it is possible
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
}
C++
In C++ an exception can be of any copyable type, this includes int's, other primitives, as well as objects.
Defining exceptions
struct MyException
{
// data with info about exception
};
However thrown exceptions should almost always derive from std::exception. The advantage of doing so is that you can catch unknown exceptions and still get some meaningful information. There are also more specific classes like std::runtime_error which also derive from std::exception.
#include <exception>
struct MyException: std::exception
{
virtual const char* what() const noexcept { return "description"; }
}
Throw exceptions
void foo()
{
throw MyException();
}
Catching exceptions
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
}
Clojure
Expression handling in Clojure is basically like Java in S-expressions:
(try
(if (> (rand) 0.5)
(throw (RuntimeException. "oops!"))
(println "see this half the time")
(catch RuntimeException e
(println e)
(finally
(println "always see this"))
ColdFusion
Catch Exceptions
inside <cfscript>:
try {
foo();
} catch (Any e) {
// handle exception e
}
otherwise:
<cftry>
<cfcatch type="Database|...">
</cfcatch>
</cftry>
Common Lisp
The Common Lisp condition system allows much more control over condition signaling and condition handling than many exception-based systems. The following example, however, simply defines a condition type, unexpected-odd-number
, defines a function get-number
which generates a random number, returning it if it is even, but signaling an unexpected-odd-number
condition if it is odd. The function get-even-number
uses handler-case
to call get-number
returning its result if no condition is signaled, and, in the case that an unexpected-odd-number
condition is signaled, returning one plus the odd number.
(define-condition unexpected-odd-number (error)
((number :reader number :initarg :number))
(:report (lambda (condition stream)
(format stream "Unexpected odd number: ~w."
(number condition)))))
(defun get-number (&aux (n (random 100)))
(if (not (oddp n)) n
(error 'unexpected-odd-number :number n)))
(defun get-even-number ()
(handler-case (get-number)
(unexpected-odd-number (condition)
(1+ (number condition)))))
A good introduction to Lisp's condition system is the chapter Beyond Exception Handling: Conditions and Restarts from Peter Seibel's Practical Common Lisp.
In Common Lisp, there are functions throw
and catch
, but these are not related to the condition system. Rather, they provide another mechanism for non-local control transfer.
D
import std.stdio;
/// Throw Exceptions
/// Stack traces are generated compiling with the -g switch.
void test1() {
throw new Exception("Sample Exception");
}
/// Catch Exceptions
void test2() {
try {
test1();
} catch (Exception ex) {
writeln(ex);
throw ex; // rethrow
}
}
/// Ways to implement finally
void test3() {
try test2();
finally writeln("test3 finally");
}
/// Or also with scope guards
void test4() {
scope(exit) writeln("Test4 done");
scope(failure) writeln("Test4 exited by exception");
scope(success) writeln("Test4 exited by return or function end");
test2();
}
void main() {
test4();
}
Delphi
Throw Exceptions
procedure test;
begin
raise Exception.Create('Sample Exception');
end;
Catch Exceptions
procedure test2;
begin
try
test;
except
ShowMessage(Exception(ExceptObject).Message); // Showing exception message
raise; // Rethrowing
end;
end;
Ways to implement finally
procedure test3;
begin
try
test2;
finally
ShowMessage('test3 finally');
end;
end;
Dyalect
func Integer.Add(x) {
throw @NegativesNotAllowed(x) when x < 0
this + x
}
try {
12.Add(-5)
} catch {
@NegativesNotAllowed(x) => print("Negative number: \(x)")
}
DWScript
Throw Exceptions
procedure Test;
begin
raise Exception.Create('Sample Exception');
end;
Catch Exceptions
procedure Test2;
begin
try
test;
except
on E: Exception do begin // Filter by exception class
PrintLn(E.Message); // Showing exception message
raise; // Rethrowing
end;
end;
end;
Ways to implement finally
procedure Test3;
begin
try
test2;
finally
PrintLn('Test3 finally');
end;
end;
Déjà Vu
stuff-going-wrong:
raise :value-error
try:
stuff-going-wrong
catch value-error:
!print "Whoops!"
- Output:
Whoops!
E
Exceptions
An exception object describes what the problem is and has nothing to do with control flow.
Due to E's ancestry as a JVM scripting language, E does not yet have any standard mechanism for user-defined exception types.
A string provided in place of an exception will be coerced to a generic exception object.
There are two control flow constructs used with exceptions: throw and eject.
Throw and catch
throw
is the built-in function which throws exceptions in the conventional sense: control goes to the catch
block of the most recently entered try
/catch
construct.
def nameOf(arg :int) {
if (arg == 43) {
return "Bob"
} else {
throw("Who?")
}
}
def catching(arg) {
try {
return ["ok", nameOf(arg)]
} catch exceptionObj {
return ["notok", exceptionObj]
}
}
? catching(42)
# value: ["not ok", problem: Who?]
? catching(43)
# value: ["ok", "Bob"]
? catching(45.7)
# value: ["not ok", problem: the float64 45.7 doesn't coerce to an int]
However, there is a problem here: exceptions accidentally produced or uncaught from inside a given module can lead to the calling program getting information about the internals that it shouldn't have (possibly a security problem). As a result of this, we are planning to move to a 'sealed exception' model where throw and catch have the same control flow, but only debuggers can see any information in a caught exception other than "a throw happened". For situations where the caller should have information about what happened, the ejector mechanism will be used.
Ejectors
Ejectors provide the same sort of "exit to catch block" control flow that throw/catch do, but with an explicit path rather than implicitly "nearest enclosing". Ejectors are also used as a general purpose control construct as well as for exceptions.
The escape ej { body } catch pat { catch block }
construct creates an ejector object and binds it to ej, which is valid for as long as body is executing. An ejector object is a function; if it is called, then control immediately passes to the catch block, with its argument bound to pat.
The above code rewritten to use ejectors:
def nameOf(arg :int, ejector) {
if (arg == 43) {
return "Bob"
} else {
ejector("Who?")
}
}
def catching(arg) {
escape unnamed {
return ["ok", nameOf(arg, unnamed)]
} catch exceptionObj {
return ["notok", exceptionObj]
}
}
? catching(42)
# value: ["not ok", problem: Who?]
? catching(43)
# value: ["ok", "Bob"]
? catching(45.7)
# problem: the float64 45.7 doesn't coerce to an int
Note that the escape-catch block does not catch the coercion error resulting from passing a float64 instead of an int, since that is an (implicit) throw.
(One further refinement: While an ejector is an ordinary function, which does not return, it is generally desirable to protect against being supplied a function which unexpectedly does return. For this purpose we have throw.eject
which calls the supplied function and throws if that function returns: throw.eject(ejector, "Who?")
)
The benefit of using ejectors to communicate exceptions, besides the information-leak prevention described above, is that only exceptions intended to be handled by that catch block will be passed to it; unexpected internal errors will be handled by general try/catch handlers.
For example, suppose we have nameOf written as follows:
var nameTable := null
def nameOf(arg :int, ejector) {
if (nameTable == null) {
nameTable := <import:nameTableParser>.parseFile(<file:nameTable.txt>)
}
if (nameTable.maps(arg)) {
return nameTable[arg]
} else {
ejector(makeNotFoundException("Who?"))
}
}
Suppose that loading the parser, or reading the file, throws a NotFoundException (note this exception type was made up for this example). Even though it is of the same type as the "Who?" exception, it will not be caught by the caller's escape/catch block since it was not passed via the ejector, whereas a traditional "try { ... } catch ex :NotFoundException { ... }" as in other languages would, leading to incorrect handling of the error.
Elena
Defining exceptions
class MyException : Exception
{
constructor new()
<= new("MyException raised");
}
Throw exceptions
foo()
{
MyException.raise()
}
Catching exceptions
try
{
o.foo()
}
catch:(MyException e)
{
// handle exceptions of type MyException and derived
}
Catching any exception
o.foo() | on:(e)
{
// handle any type of exception
};
Erlang
-module( exceptions ).
-export( [task/0] ).
task() ->
try
erlang:throw( new_exception )
catch
_:Exception -> io:fwrite( "Catched ~p~n", [Exception] )
end.
- Output:
14> exceptions:task(). Catched new_exception
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
Fancy
# define custom exception class
# StandardError is base class for all exception classes
class MyError : StandardError {
def initialize: message {
# forward to StdError's initialize method
super initialize: message
}
}
try {
# raises/throws a new MyError exception within try-block
MyError new: "my message" . raise!
} catch MyError => e {
# catch exception
# this will print "my message"
e message println
} finally {
# this will always be executed (as in e.g. Java)
"This is how exception handling in Fancy works :)" println
}
Fantom
// Create a new error class by subclassing sys::Err
const class SpecialErr : Err
{
// you must provide some message about the error
// to the parent class, for reporting
new make () : super ("special error") {}
}
class Main
{
static Void fn ()
{
throw SpecialErr ()
}
public static Void main ()
{
try
fn()
catch (SpecialErr e)
echo ("Caught " + e)
}
}
- Output:
$ fan exceptions.fan Caught exceptions_0::SpecialErr: special error
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
FreeBASIC
FreeBASIC does not support exceptions or the Try/Catch/Finally statement, as such. However, you can use the Err() function, together with a Switch statement, to provide somewhat similar functionality:
' FB 1.05.0 Win64
Enum ErrorType
myError = 1000
End Enum
Sub foo()
Err = 1000 ' raise a user-defined error
End Sub
Sub callFoo()
foo()
Dim As Long errNo = Err ' cache Err in case it's reset by a different function
Select Case errNo
Case 0
' No error (system defined)
Case 1 To 17
' System defined runtime errors
Case myError: ' catch myError
Print "Caught myError : Error number"; errNo
Case Else
' catch any other type of errors here
End Select
' add any clean-up code here
End Sub
callfoo()
Print
Print "Press any key to quit"
Sleep
- Output:
Caught myError : Error number 1000
Gambas
Click this link to run this code
Public Sub Main()
Dim iInteger As Integer
MakeError
DivError
iInteger = "2.54"
Catch
Print Error.Text
End
'______________________
Public Sub DivError()
Print 10 / 0
Catch
Print Error.Text
End
'______________________
Public Sub MakeError()
Error.Raise("My Error")
Catch
Print Error.Text
End
Output:
My Error Division by zero Type mismatch: wanted Integer, got String instead
Go
Execution errors such as attempting to index an array out of bounds trigger a run-time panic equivalent to a call of the built-in function panic() with a value of the implementation-defined interface type runtime.Error.
panic(x) "throws" a value (of any type), and recover() "catches" it.
recover() needs to be called in a "deferred" function call, otherwise it will have no effect. defer delays the function call until the current function returns (or fails).
package main
import "fmt"
func foo() int {
fmt.Println("let's foo...")
defer func() {
if e := recover(); e != nil {
fmt.Println("Recovered from", e)
}
}()
var a []int
a[12] = 0
fmt.Println("there's no point in going on.")
panic("never reached")
panic(fmt.Scan) // Can use any value, here a function!
}
func main() {
foo()
fmt.Println("glad that's over.")
}
- Output:
let's foo... Recovered from runtime error: index out of range glad that's over.
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 -}
HolyC
HolyC has an exception handling mechanism using try/throw/catch
. Exception names are limited to a maximum of 8 bytes in length.
The catch
block does not have the capability to differentiate between specific exceptions. Instead, all exceptions for a try
block are handled by a single catch
block.
try {
U8 *err = 'Error';
throw(err); // throw exception
} catch {
if (err == 'Error')
Print("Raised 'Error'");
PutExcept; // print the exception and stack trace
}
Icon and Unicon
The following Unicon example makes use of support for exceptions found in the The Unicon Code Library. Since exception support is not built into Unicon, but rather implemented as Unicon code, there are limitations not found in languages that natively support exceptions.
import Exceptions
procedure main(A)
every i := !A do {
case Try().call{ write(g(i)) } of {
Try().catch(): {
x := Try().getException()
write(x.getMessage(), ":\n", x.getLocation())
}
}
}
end
procedure g(i)
if numeric(i) = 3 then Exception().throw("bad value of "||i)
return i
end
A sample run is:
-> ExceptionTest 1 2 3 4 5 1 2 Exception: bad value of 3: procedure g [ExceptionTest.icn:15] procedure main [ExceptionTest.icn:5] 4 5 ->
Note: it may be possible to implement exceptions in Icon; however, it would require a major rework and would likely be inelegant.
J
Tacit
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.
Explicit
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
}
Java 7 added "multicatch" and "smart rethrow".
public void foo() throws UnsupportedDataTypeException{
try{
throwsNumberFormatException();
//the following methods throw exceptions which extend IOException
throwsUnsupportedDataTypeException();
throwsFileNotFoundException();
}catch(FileNotFoundException | NumberFormatException ex){
//deal with these two Exceptions without duplicating code
}catch(IOException e){
//deal with the UnsupportedDataTypeException as well as any other unchecked IOExceptions
throw e;
}
}
In previous versions of Java, foo()
would have to declare that it throws an IOException
. The "smart rethrow" recognizes that the only checked exception that can result in the rethrow ("throw e;
") is an UnsupportedDataTypeException
. The last catch block will still catch any other unchecked IOException
s and rethrow them, but foo()
only needs to declare that UnsupportedDataTypeException
s are thrown from it since that's the only checked exception that can cause a rethrow.
The other catch block uses the same code to handle both FileNotFoundException
s and NumberFormatException
s by adding a |
between the exception types that are declared.
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;
}
jq
The ability to "catch" exceptions was introduced after jq version 1.4 was released and so a brief explanation is included here.
Exceptions, as before, can be raised by the execution of an error statement: error(STRING)
The "try" clause takes the form:
try FILTER catch CATCHER
where FILTER and CATCHER may be any jq expressions.
Within a "try" clause, . is the value of the STRING of the exception that has been caught.
Example:
def division(a;b):
def abs: if . < 0 then -. else . end;
if a == 0 and b == 0 then error("0/0")
elif b == 0 then error("division by 0")
elif (a|abs|log) - (b|abs|log) > 700 then error("OOB")
else a/b
end;
def test(a;b):
try division(a;b)
catch if . == "0/0" then 0
elif . == "division by 0" then null
else "\(.): \(a) / \(b)"
end;
- test(0;0) # produces 0
- test(1e300; 1e-300) # produces "OOB: 1e+300 / 1e-300"
Julia
function extendedsqrt(x)
try sqrt(x)
catch
if x isa Number
sqrt(complex(x, 0))
else
throw(DomainError())
end
end
end
@show extendedsqrt(1) # 1
@show extendedsqrt(-1) # 0.0 + 1.0im
@show extendedsqrt('x') # ERROR: DomainError
Kotlin
// version 1.0.6
// In Kotlin all Exception classes derive from Throwable and, by convention, end with the word 'Exception'
class MyException (override val message: String?): Throwable(message)
fun foo() {
throw MyException("Bad foo!")
}
fun goo() {
try {
foo()
}
catch (me: MyException) {
println("Caught MyException due to '${me.message}'")
println("\nThe stack trace is:\n")
me.printStackTrace()
}
}
fun main(args: Array<String>) {
goo()
}
- Output:
Caught MyException due to 'Bad foo!' The stack trace is: MyException: Bad foo! at ExceptionKt.foo(exception.kt:7) at ExceptionKt.goo(exception.kt:12) at ExceptionKt.main(exception.kt:22)
langur
A catch causes all the statements preceding it within a block to be the implicit try block.
Exceptions in langur are hashes guaranteed to contain certain fields, even if they're empty.
# do something
throw "not a math exception"
catch .e {
if .e["cat"] == "math" {
# change result...
} else {
# rethrow the exception
throw
}
} else {
# no exception
...
}
An else section on a catch is optional. As of 0.7, you can also use else if on a catch.
shortened catch
A catch can be shortened by using a single expression that does not start with a variable name. This uses the implicit _err exception variable. Prior to 0.7, the implicit exception variable was .err.
A shortened catch does not allow an else section (action for no exception).
100 / 0
catch if _err["cat"] == "math" {
# change result
123
} else {
throw
}
val .safediv = f { .x / .y ; catch 0 }
.safediv(7, 7) # 1
.safediv(7, 0) # 0
Lasso
protect => {
handle_error => {
// do something else
}
fail(-1,'Oops')
}
Lingo
Lingo has no try...catch mechanism. A script error will always end execution of the current call stack. There is however a mechanism that prevents that script errors quit the execution of the current movie/projector: you can set up an "alertHook" that is called when such errors occur. This alertHook can then e.g. log the error to a file or database, and if it returns 1, the movie/projector continues to play:
-- parent script "ErrorHandler"
on alertHook (me, errorType, errorMessage, alertType)
if alertType=#alert then return 0 -- ignore programmatic alerts
-- log error in file "error.log"
fn = _movie.path&"error.log"
fp = xtra("fileIO").new()
fp.openFile(fn, 2)
if fp.status() = -37 then
fp.createFile(fn)
fp.openFile(fn, 2)
end if
fp.setPosition(fp.getLength())
fp.writeString(_system.date() && _system.time() && errorType & ": " & errorMessage & RETURN)
fp.closeFile()
return 1 -- continues movie playback, no error dialog
end
-- in a movie script
on prepareMovie
_player.alertHook = script("ErrorHandler")
end
In terms of the behavior described above, a "throw" command triggering custom errors that behave exactly like real script errors can be implemented like this:
-- in a movie script
-- usage: throw("Custom error 23")
on throw (msg)
_player.alertHook.alertHook("Script runtime error", msg, #script)
abort() -- exits call stack
end
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
Logtalk
Logtalk exception-handling mechanism is based on the catch/3 and throw/1 predicates inherited from Prolog:
:- object(exceptions).
:- public(double/2).
double(X, Y) :-
catch(double_it(X,Y), Error, handler(Error, Y)).
handler(error(not_a_number(X), logtalk(This::double(X,Y), Sender)), Y) :-
% try to fix the error and resume computation;
% if not possible, rethrow the exception
( catch(number_codes(Nx, X), _, fail) ->
double_it(Nx, Y)
; throw(error(not_a_number(X), logtalk(This::double(X,Y), Sender)))
).
double_it(X, Y) :-
( number(X) ->
Y is 2*X
; this(This),
sender(Sender),
throw(error(not_a_number(X), logtalk(This::double(X,Y), Sender)))
).
:- end_object.
- Output:
| ?- exceptions::double(1, Double). Double = 2 yes | ?- exceptions::double("1", Double). Double = 2 yes | ?- exceptions::double(a, Double). uncaught exception: error(not_a_number(a),logtalk(exceptions::double(a,_),user))
Lua
Throwing an Exception
error("Something bad happened!")
Catching Exceptions
function throw_error()
error("Whoops")
-- won't ever appear, due to previous error() call
return "hello!"
end
-- 'status' is false if 'throw_error' threw an error
-- otherwise, when everything went well, it will be true.
-- 'errmsg' contains the error message, plus filename and line number of where the error occured
status, errmsg = pcall(throw_error)
print("errmsg = ", errmsg)
Note that `pcall` passes every argument after the function object or function name to said function:
function throw_error_with_argment(argument)
error(string.format("Whoops! argument = %s", argument))
-- won't ever appear, due to previous error() call
return "hello!"
end
status, errmsg = pcall(throw_error_with_argment, "foobar 123")
print("errmsg = ", errmsg)
If a function does not throw an error, 'errmsg' (which might be called 'returned' as well) contains the value(s) returned from the function:
function throw_error_with_argment(argument)
return "hello!"
end
status, errmsg = pcall(throw_error_with_argment, "foobar 123")
print("errmsg = ", errmsg)
M2000 Interpreter
Module Errors {
Module Check {
Module Error1 {
A=1/0
}
Try ok {
Error1
}
' we get an Error, and Error$ print division by zero in module Error1
If Error or not ok then Print Error$
Error "New Error"
}
Try {
Check
}
Print Error=0 ' no Error return
Print Error$ ' but Error message isn't clear
' Error$ used one time, then cleared automatic
}
Errors
Print Error$=""
- Output:
division by zero in module ERROR1 True New Error in module CHECK True
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
Maple
errorproc:=proc(n)
local a;
try
a:=1/n;
catch "numeric exception: division by zero":
error "Something went wrong when dividing."
end try;
end proc;
Mathematica / Wolfram Language
f[x_] := If[x > 10, Throw[overflow], x!]
Example usage :
Catch[f[2] + f[11]]
-> overflow
Catch[f[2] + f[3]]
-> 8
MATLAB
Errors are thrown using the "error" keyword.
Sample usage:
>> error 'Help'
??? Help
Modula-3
Defining exceptions
Exceptions can only be declared at the "top-level" of a module or interface. Arguments are optional.
EXCEPTION EndOfFile;
EXCEPTION Error(TEXT);
Throw exceptions
Exceptions can be bound to procedures using RAISES:
PROCEDURE Foo() RAISES { EndOfFile } =
...
RAISE EndOfFile;
...
Catching exceptions
TRY
Foo();
EXCEPT
| EndOfFile => HandleFoo();
END;
Modula-3 also has a FINALLY keyword:
TRY
Foo();
FINALLY
CleanupFoo(); (* always executed *)
END;
MOO
Throw exceptions
Values can be raised to exceptions using raise():
raise(E_PERM);
Catching exceptions
try
this:foo();
except e (ANY)
this:bar(e);
endtry
MOO also has a finally statement:
try
this:foo();
finally
this:bar();
endtry
Shorthand
`this:foo()!ANY=>this:bar()';
Nanoquery
try
invalid "this statement will fail"
catch e
println "caught an exception"
println e
end try
Throwing exceptions:
throw new(Exception, "exception reason as string")
Nemerle
// define a new exception
class MyException : Exception
{
...
}
// throw an exception
Foo() : void
{
throw MyException();
}
// catching exceptions
try {
Foo();
}
catch { // catch block uses pattern matching syntax
|e is MyException => ... // handle exception
|_ => throw e // rethrow unhandled exception
}
finally {
... // code executes whether or not exception was thrown
}
NetRexx
As NetRexx runs under the control of a JVM it has the same exception model as Java.
/* NetRexx */
options replace format comments java crossref symbols nobinary
-- =============================================================================
class RExceptions public
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method test() public signals RExceptions.TakeException
if (1 == 1) then signal RExceptions.TakeException()
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method main(args = String[]) public static
do
RExceptions().test()
catch ex = Exception
say ex.toString()
end
return;
-- =============================================================================
class RExceptions.TakeException public extends Exception
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method TakeException() public
super('I resent that!')
return
Output:
RExceptions$TakeException: I resent that!
Nim
Defining exceptions
type SillyError = object of Exception
Throwing an exception
proc spam() =
raise newException(SillyError, "Some error")
Handling an exception
try:
spam()
except SillyError:
echo "Got SillyError with message: ", getCurrentExceptionMsg()
except:
echo "Got another exception"
finally:
echo "Finally"
Objective-C
Defining exceptions
Exceptions can be any Objective-C object, though they are usually instances of NSException
. You can create a subclass of NSException if necessary:
@interface MyException : NSException {
//Put specific info in here
}
@end
Throw exceptions
- (void)foo {
@throw [NSException exceptionWithName:@"TerribleException"
reason:@"OMGWTFBBQ111!1" userInfo:nil];
}
Catching exceptions
@try {
[self foo];
}
@catch (MyException *exc) {
//Catch only your specified type of exception
}
@catch (NSException *exc) {
//Catch any NSException or subclass
NSLog(@"caught exception named %@, with reason: %@", [exc name], [exc reason]);
}
@catch (id exc) {
//Catch any kind of object
}
@finally {
//This code is always executed after exiting the try block
}
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"
Oforth
Oforth uses try/when blocks to trap exceptions and throw to throw an execption
It is also possible to create new exception classes (see Exception.of).
: iwillThrowAnException "A new exception" Exception throw ;
: iwillCatch
| e |
try: e [ iwillThrowAnException ] when: [ "Exception catched :" . e .cr ]
try: e [ 1 2 over last ] when: [ "Exception catched :" . e .cr ]
"Done" println ;
- Output:
Exception catched : A new exception Exception catched : 1 does not understand #last Done
Oz
Throw exceptions
Any value can be thrown as an exception. Typically record values are used.
raise sillyError end
raise slightlyLessSilly(data:42 reason:outOfMemory) end
By using a record value with a feature debug
set to unit
you can indicate that the exception shall have debug information (including a stack trace).
try
raise someError(debug:unit) end
catch someError(debug:d(stack:ST ...)...) then
{Inspect ST}
end
See also: Exceptions in the Oz documentation.
Catching exceptions
Exception are caught with pattern matching. Ellipsis indicating additional optional fields are often useful here.
try
{Foo}
catch sillyError then
{Bar}
[] slightlyLessSilly(data:D ...) then
{Quux D}
[] _ then %% an unknown type of exception was thrown
{Baz}
finally
{Fin}
end
PARI/GP
Catching errors in GP
The errors that can be trapped in GP are:
alarmer
|
generic error |
gdiver
|
division by 0 |
invmoder
|
impossible modular inverse |
archer
|
not available on this architecture or operating system |
typeer
|
wrong type |
errpile
|
the PARI stack overflows |
talker
|
generic error |
user
|
User-initiated error |
trap(/* specific error can be given here, or leave blank to catch all */,
"caught"
,
error("bad stuff")
)
Throwing errors in GP
The only error that can be thrown in GP is user error:
error("Text of error here")
Throwing errors in PARI
Many more errors can be caught and thrown directly in PARI:
pari_err(arither1, "functionName"); // Gives "*** functionName: not an integer argument in an arithmetic function"
Catching errors in PARI
It is rare that this mechanism needs to be used in PARI, rather than standard C methods, but the function closure_trapgen
(similar to closure_evalgen
) is available:
GEN x = closure_trapgen(arither1, f); // Executes the function f, catching "not an integer argument in an arithmetic function" errors
if (x == (GEN)1L) // Was there an error?
pari_printf("Don't do that!\n"); // Recover
Pascal
See Delphi
Perl
Using eval
Exceptions using the core eval function:
# 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 advanced object based-exception handling.
Using Try::Tiny
The same using the Try::Tiny module:
# throw an exception
die "Danger, danger, Will Robinson!";
# catch an exception and show it
try {
die "this could go wrong mightily";
} catch {
print;
};
# rethrow (inside of catch)
die $_;
Other styles
More complicated exception handling can be achieved in Perl using TryCatch or Exception::Class modules.
Phix
Phix provides try/catch and throw statements.
Throwing exceptions
You can throw any string (on it's own) or any integer, optionally with any (deeply nested) user_data that you like.
throw("oh no")
throw(1)
throw(501,{"she",made[me],Do(it)})
Catching exceptions
There is one and only one non-optional catch clause per try statement.
The variable caught is a sequence, augmented with run-time diagnostics, with whatever was thrown in e[E_CODE] and/or e[E_USER].
try one_of(these) catch e if e[E_CODE]=501 then puts(1,"that's no excuse!\n") else throw(e) end if end try
An uncaught exception terminates the program in error, otherwise control resumes in the catch clause or after the end try,
with no means (apart from some really nasty inline assembly) of resuming any half-finished block of code, and indeed any
call stack entries between a throw and a catch will already have been torn down and thrown away.
Traditionally fatal errors are re-routed via throw() when the presence of an exception handler is detected.
There is no absurdly confusing finally construct - trivial to mimic better with the introduction of a single simple boolean flag anyway.
PHL
PHL does not support multiple catch-clauses.
module exceptions;
extern printf;
struct @MyException : @Exception {
};
@Void func throws ex [
throw new @MyException;
]
@Integer main [
try func();
catch (e) {
if (e::getType == "MyException") {
printf("MyException thrown!\n");
} else {
printf("Unhandled exception!\n");
}
}
return 0;
]
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();
}
PicoLisp
catch, throw (and finally) can be used for exception handling. 'throw' will transfer control to a 'catch' environment that was set up with the given label.
(catch 'thisLabel # Catch this label
(println 1) # Do some processing (print '1')
(throw 'thisLabel 2) # Abort processing and return '2'
(println 3) ) # This is never reached
- Output:
1 # '1' is printed -> 2 # '2' is returned
PL/I
/* Define a new exception, called "my_condition". */
on condition (my_condition) snap begin;
put skip list ('My condition raised.');
end;
/* Raise that exception */
signal condition (my_condition);
/* Raising that exception causes the message "My condition raised" */
/* to be printed, and execution then resumes at the statement */
/* following the SIGNAL statement. */
PL/pgSQL
Raise an exception
begin
raise exception 'this is a generic user exception';
raise exception division_by_zero;
end;
Handle an exception
Hande division by zero and re-raising once caught other exception:
create function special_division(p_num double precision, p_den double precision) returns text
as $body$
begin
return p_num/p_den::text;
EXCEPTION
when division_by_zero then
if p_num>0 then
return 'Inf';
ELSIF p_num<0 then
return '-Inf';
else
return 'INDEF';
end if;
when others then
raise;
end;
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();
PowerShell
Throw an exception:
throw "Any error message."
- Output:
Any error message. At line:1 char:1 + throw "Any error message." + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (Any error message.:String) [], RuntimeException + FullyQualifiedErrorId : Any error message.
Throw a more specific exception:
throw [System.IO.FileNotFoundException] ".\temp.txt not found."
- Output:
.\temp.txt not found. At line:1 char:1 + throw [System.IO.FileNotFoundException] ".\temp.txt not found." + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], FileNotFoundException + FullyQualifiedErrorId : .\temp.txt not found.
Using try {} catch {}
is better for more complex error checking because you can test specific errors:
try
{
Get-Content -Path .\temp.txt
}
catch [System.IO.FileNotFoundException]
{
Write-Host "File not found exception"
}
catch [System.Exception]
{
Write-Host "Other exception"
}
- Output:
Get-Content : Cannot find path 'C:\Users\Owner\temp.txt' because it does not exist. At line:4 char:5 + Get-Content -Path .\temp.txt + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Users\Owner\temp.txt:String) [Get-Content], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
Errors are objects like any other in PowerShell, so you may capture any detail of it:
$Error[0] | Get-Member
- Output:
TypeName: System.Management.Automation.ErrorRecord Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serial... GetType Method type GetType() ToString Method string ToString() writeErrorStream NoteProperty bool writeErrorStream=True CategoryInfo Property System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;} ErrorDetails Property System.Management.Automation.ErrorDetails ErrorDetails {get;set;} Exception Property System.Exception Exception {get;} FullyQualifiedErrorId Property string FullyQualifiedErrorId {get;} InvocationInfo Property System.Management.Automation.InvocationInfo InvocationInfo {get;} PipelineIterationInfo Property System.Collections.ObjectModel.ReadOnlyCollection[int] PipelineIterationInfo {get;} ScriptStackTrace Property string ScriptStackTrace {get;} TargetObject Property System.Object TargetObject {get;} PSMessageDetails ScriptProperty System.Object PSMessageDetails {get=& { Set-StrictMode -Version 1; $this.Exception.InnerExcep...
Prolog
foo(X) :-
\+ integer(X),
throw(b('not even an int')).
foo(X) :-
\+ between(1,10,X),
throw(a('must be between 1 & 10')).
foo(X) :-
format('~p is a valid number~n', X).
go(X) :-
catch(
foo(X),
E,
handle(E)).
handle(a(Msg)) :-
format('~w~n', Msg),
!.
handle(X) :- throw(X).
- Output:
?- go(1). 1 is a valid number true. ?- go(5). 5 is a valid number true. ?- go(11). must be between 1 & 10 true. ?- go(test). ERROR: Unhandled exception: b('not even an int') ?-
PureBasic
Procedure ErrorHandler()
MessageRequester("Exception test", "The following error happened: " + ErrorMessage())
EndProcedure
MessageRequester("Exception test", "Test start")
OnErrorCall(@ErrorHandler())
RaiseError(#PB_OnError_InvalidMemory) ;a custom error# can also be used here depending on the OS being compiled for
Python
Defining an exception
import exceptions
class SillyError(exceptions.Exception):
def __init__(self,args=None):
self.args=args
Note: In most cases new exceptions are defined simply using the pass statement. For example:
class MyInvalidArgument(ValueError):
pass
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:
def spam():
raise SillyError # equivalent to raise SillyError()
Passing an argument to the constructor of an exception class:
def spam():
raise SillyError, 'egg' # equivalent to raise SillyError('egg')
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.
def spam():
raise SillyError('egg')
Handling an exception
try-except-else-finally
try:
foo()
except SillyError, se:
print se.args
bar()
else:
# no exception occurred
quux()
finally:
baz()
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
try:
foo()
except SillyError as se:
print(se.args)
bar()
else:
# no exception occurred
quux()
finally:
baz()
Quackery
As the overwhelming majority of Quackery is open and accessible to the programmer Exception Handling cannot be fully automated. The full explanation is contained in The Book of Quackery, downloadable as a pdf from the GitHub Quackery repository, section Word Behaviours, subsection Exception Handling.
Here we will consider "typical" usage, which will restore as much of the system state as is usually required when an exception is raised. (i.e. excluding the compiler's dictionaries, and not including any special actions to compensate for breaches of the conventions which Quackery has instead of strictly enforced rules.)
Consider a Quackery word a
composed of other Quackery words to an arbitrary level of nesting, and somewhere within that code a condition is detected which requires one to backtrack to just before a
was invoked, and follow an alternate path, b
. Additionally, some information regarding the reason for bailing out of a
is required, for example a string of text describing the reason for abandoning path a
.
When the condition is detected, a
, or one of the words it invokes, will put a suitable message on the system ancillary stack called message
, and invoke the word bail
.
<flag on stack indicating if condition detected>
if [ $ "It all went pear shaped in 'a'." message put bail ]
The one piece of necessary information about changes to the system state that Quackery cannot infer, even in "typical" usage, is the maximum number of items on the stack that may be removed or replaced during the execution of a
. This needs to be specified by the programmer. (If the programmer is following conventions about stack comments, this could be gleaned from a
's stack comment, but Quackery steadfastly disregards all comments.) In this example, a
consumes three stack items, so that is included in the code. How many it returns if there is no exception raised is not necessary information.
3 backup a bailed if [ message take echo$ b ]
backup
makes a copy of the 3 topmost items on the stack and performs other necessary actions to ensure that the system state can be restored if bail
is invoked during the execution of a
.
If bail
is not invoked, bailed
disposes of the state information saved by backup
and leaves false
on the stack, so the nest following if
is not executed.
If bail
is invoked, bailed
restores the system state and leaves true
on the stack, so the nest following if
is executed, in this example printing the text It all went pear shaped in 'a'.
on the screen and executing the Quackery word b
.
R
Define an exception
e <- simpleError("This is a simpleError")
Raise an exception
stop("An error has occured")
stop(e) #where e is a simpleError, as above
Handle an exception
tryCatch(
{
if(runif(1) > 0.5)
{
message("This doesn't throw an error")
} else
{
stop("This is an error")
}
},
error = function(e) message(paste("An error occured", e$message, sep = ": ")),
finally = message("This is called whether or not an exception occured")
)
Racket
#lang racket
;; define a new exception type
(struct exn:my-exception exn ())
;; handler that prints the message ("Hi!")
(define (handler exn)
(displayln (exn-message exn)))
;; install exception handlers
(with-handlers ([exn:my-exception? handler])
;; raise the exception
(raise (exn:my-exception "Hi!" (current-continuation-marks))))
Raku
(formerly Perl 6)
The Raku equivalent to Perl 5's eval {...} is try {...}. A try block by default has a CATCH block that handles all fatal exceptions by ignoring them. If you define a CATCH block within the try, it replaces the default CATCH. It also makes the try keyword redundant, because any block can function as a try block if you put a CATCH block within it. The inside of a CATCH functions as a switch statement on the current exception.
try {
die "Help I'm dieing!";
CATCH {
when X::AdHoc { note .Str.uc; say "Cough, Cough, Aiee!!" }
default { note "Unexpected exception, $_!" }
}
}
say "Yay. I'm alive.";
die "I'm dead.";
say "Arrgh.";
CATCH {
default { note "No you're not."; say $_.Str; }
}
HELP I'M DIEING! Cough, Cough, Aiee!! Yay. I'm alive. No you're not. I'm dead.
Rake comes with phasers, that are called when certain conditions in the life of a program, routine or block are met. CATCH is one of them and works nicely together with LEAVE that is called even if an exception would force the current block to be left immediately. It's a nice place to put your cleanup code.
sub f(){
ENTER { note '1) f has been entered' }
LEAVE { note '2) f has been left' }
say '3) here be dragons';
die '4) that happend to be deadly';
}
f();
say '5) am I alive?';
CATCH {
when X::AdHoc { note q{6) no, I'm dead}; }
}
1) f has been entered 3) here be dragons 6) no, I'm dead 2) f has been left
Raven
42 as custom_error
define foo
custom_error throw
try
foo
catch
custom_error =
if 'oops' print
REXX
While the REXX language doesn't have a throw capability per se,
it does have the ability to catch exceptions (by label).
This type of exception handling (in REXX) has its limitation
(the label is local to the program, not external subroutines).
/*REXX program demonstrates handling an exception (negative #); catching is via a label.*/
do j=9 by -5
say 'the square root of ' j " is " sqrt(j)
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); h=d+6; m.=9
numeric digits; numeric form; if x<0 then signal .sqrtNeg
parse value format(x, 2, 1, , 0) 'E0' with g 'E' _ .; g=g * .5'e'_ % 2
do j=0 while h>9; m.j=h; h=h%2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g) * .5; end /*k*/
numeric digits d; return g/1
.sqrtNeg: say 'illegal SQRT argument (argument is negative):' x; exit 13
output
the square root of 9 is 3 the square root of 4 is 2 illegal SQRT argument (argument is negative): -1
Ring
Try
see 1/0
Catch
raise("Sorry we can't divide 1/0 + nl)
Done
Ruby
Defining an exception
# define an exception
class SillyError < Exception
end
SillyError is simply declared as a subclass of Exception. No over-riding is necessary.
class MyInvalidArgument < ArgumentError
end
MyInvalidArgument is a type of ArgumentError (a built-in class). 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.
Handling an exception
# raise (throw) an exception
def spam
raise SillyError, 'egg'
end
# rescue (catch) an exception
begin
spam
rescue SillyError => se
puts se # writes 'egg' to stdout
end
begin
foo
rescue ArgumentError => e
# rescues a MyInvalidArgument or any other ArgumentError
bar
rescue => e
# rescues a StandardError
quack
else
# runs if no exception occurred
quux
ensure
# always runs
baz
end
ArgumentError is a type of StandardError, but Ruby uses the first matching "rescue" clause. So we never "quack" for an ArgumentError, but we only "bar" for it.
The "rescue" clause is like the "catch" clause in other languages. The "ensure" clause is like the "finally" clause in other languages.
# short way to rescue any StandardError
quotient = 1 / 0 rescue "sorry"
The short form "a rescue b" returns a, but if a raises a StandardError, then it returns b. (ZeroDivisionError is a subclass of StandardError.)
Catch and throw
Ruby has a separate exception-like system that is meant to be used to exit out of deep executions that are not errors.
def foo
throw :done
end
catch :done do
foo
end
With Ruby 1.8, you can only "throw" and "catch" symbols. With Ruby 1.9, you can throw and catch any object. Like exceptions, the throw can be made from a function defined elsewhere from the catch block.
Rust
In Rust, there is no concept of "exception" per se.
Functions return a Result that can be either an error or a success, and the programmer can chose to panic on an error or not. It is illustrated by the code below:
// IO error is used here just as an example of an already existing
// Error
use std::io::{Error, ErrorKind};
// Rust technically doesn't have exception, but different
// types of error handling. Here are two examples of results.
fn valid_function() -> Result<usize, Error> {
Ok(100)
}
fn errored_function() -> Result<usize, Error> {
Err(Error::new(ErrorKind::Other, "Something wrong happened."))
}
// This should happen only when an unrecoverable error happened
fn panicking_function() {
panic!("Unrecoverable state reached");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_function() {
let result = match valid_function() {
Ok(number) => number,
Err(_) => panic!("This is not going to happen"),
};
assert_eq!(result, 100);
}
#[test]
fn test_errored_function() {
let result = match errored_function() {
Ok(_) => panic!("This is not going to happen"),
Err(e) => {
assert_eq!(e.to_string(), "Something wrong happened.");
0
}
};
assert_eq!(result, 0);
}
#[test]
#[should_panic]
fn test_panicking_function() {
panicking_function();
}
}
Scala
In Scala there is, thank heavens, no "checked exception" doctrine. Exceptions can be freely implemented, it's the skill of the programmer to use them right. This example is bad example of using exceptions, only to show that they can be used.
In there are 3 main entries: object CheckingAccount, CheckingBlockingAccount and NotImplementedErrorTest to selective start this solution and demonstrate the working of exceptions and handling.
//Defining exceptions
class AccountBlockException extends Exception
class InsufficientFundsException(val amount: Double) extends Exception
class CheckingAccount(number: Int, var blocked: Boolean = false, var balance: Double = 0.0) {
def deposit(amount: Double) { // Throwing an exception 1
if (blocked) throw new AccountBlockException
balance += amount
}
def withdraw(amount: Double) { // Throwing an exception 2
if (blocked) throw new AccountBlockException
if (amount <= balance) balance -= amount
else throw new InsufficientFundsException(amount - balance)
}
}
object CheckingAccount extends App {
class ExampleException1 extends Exception
val c = new CheckingAccount(101)
println("Depositing $500...")
try {
c.deposit(500.00)
println("\nWithdrawing $100...")
c.withdraw(100.00)
println("\nWithdrawing $600...")
c.withdraw(600.00)
} catch { // Exception handler
case ac: InsufficientFundsException => println(s"Sorry, but you are short ${'$'} ${ac.amount}")
case ac: AccountBlockException => println("Account blocked.")
///////////////////////////// An example of multiple exception handler ////////////////////////
case e@(_: ExampleException1 |
_: InterruptedException) => println(s"Out of memory or something else.")
case e: Exception => e.printStackTrace()
case _: Throwable => // Exception cached without any action
} finally println("Have a nice day")
}
object CheckingBlockingAccount extends App {
val c = new CheckingAccount(102, true)
println("Depositing $500...")
try {
c.deposit(500.00)
println("\nWithdrawing $100...")
c.withdraw(100.00)
println("\nWithdrawing $600...")
c.withdraw(600.00)
} catch { // Exception handler
case ac: InsufficientFundsException => println(s"Sorry, but you are short ${'$'} ${ac.amount}")
case ac: AccountBlockException => println("Account blocked.")
case e: Exception => e.printStackTrace()
case _: Throwable =>
} finally println("Have a nice day")
}
object NotImplementedErrorTest extends App {
??? // Throws scala.NotImplementedError: an implementation is missing
}
- Output:
Running entry point CheckingAccount
Depositing $500... Withdrawing $100... Withdrawing $600... Sorry, but you are short $ 200.0 Have a nice day
- Output:
Running entry point CheckingBlockingAccount
Depositing $500... Account blocked. Have a nice day
- Output:
Running entry point NotImplementedErrorTest
Exception in thread "main" scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:252) at NotImplementedErrorTest$delayedInit$body.apply(CheckingAccount.scala:53) .....
Scheme
Exception handling can be created with any language supporting continuations, using as few primitves as possible, exception handling in Scheme can look like this. (But anyone wishing to continue using exceptions will abstract them into macros).
(define (me-errors xx exception)
(if (even? xx)
xx
(exception)))
;example that does nothing special on exception
(call/cc
(lambda (exception)
(me-errors 222 exception)
(display "I guess everything is alright")))
;example that laments oddness on exception
(call/cc
(lambda (all-ok) ;used to "jump" over exception handling
(call/cc
(lambda (exception-handle)
(me-errors 333 exception-handle)
(display "I guess everything is alright")
(all-ok)))
(display "oh my god it is ODD!")))
Seed7
Raise an exception
const proc: foo is func
begin
raise RANGE_ERROR;
end func;
Handle an exception
const proc: main is func
begin
block
foo;
exception
catch RANGE_ERROR:
writeln("catched RANGE_ERROR");
end block;
end func;
Sidef
An exception is thrown by the die keyword, which, if not caught, it terminates the program with an appropriate exit code.
try {
die "I'm dead!"; # throws an exception of type 'error'
}
catch { |type, msg|
say "type: #{type}"; # type: error
say "msg: #{msg}"; # msg: I'm dead! at test.sf line 2.
};
say "I'm alive...";
die "Now I'm dead!"; # this line terminates the program
say "Or am I?"; # Yes, you are!
- Output:
type: error msg: I'm dead! at test.sf line 2. I'm alive... Now I'm dead! at test.sf line 10.
Slate
Handling Exceptions
se@(SceneElement traits) doWithRestart: block
[
block handlingCases: {Abort -> [| :_ | ^ Nil]}
].
Define Exceptions
conditions define: #Abort &parents: {Restart}.
"An Abort is a Restart which exits the computation, unwinding the stack."
_@lobby abort
[
Abort signal
].
_@(Abort traits) describeOn: console
[
console ; 'Abort evaluation of expression\n'
].
"This will call:"
c@(Condition traits) signal
"Signalling a Condition."
[
c tryHandlers
].
Throwing Exceptions
(fileName endsWith: '.image') ifTrue: [error: 'Image filename specified where Slate source expected. Make sure you run slate with the -i flag to specify an image.'].
Smalltalk
Throwing an Exception
"exec" "gst" "-f" "$0" "$0" "$*"
"exit"
Transcript show: 'Throwing yawp'; cr.
self error: 'Yawp!'.
$ ./yawp.st
Throwing yawp
Object: nil error: Yawp!
Error(Exception)>>signal (AnsiExcept.st:216)
Error(Exception)>>signal: (AnsiExcept.st:226)
UndefinedObject(Object)>>error: (AnsiExcept.st:1565)
UndefinedObject>>executeStatements (yawp.st:5)
Handling an Exception
"exec" "gst" "-f" "$0" "$0" "$*"
"exit"
[
Transcript show: 'Throwing yawp'; cr.
self error: 'Yawp!'.
] on: Error do: [ :e |
Transcript show: 'Caught yawp'; cr.
].
$ ./yawp.st
Throwing yawp
Caught yawp
SQL PL
With SQL PL:
--#SET TERMINATOR @
BEGIN
DECLARE numerator INTEGER DEFAULT 12;
DECLARE denominator INTEGER DEFAULT 0;
DECLARE result INTEGER;
DECLARE overflow CONDITION for SQLSTATE '22003' ;
DECLARE CONTINUE HANDLER FOR overflow
RESIGNAL SQLSTATE '22375'
SET MESSAGE_TEXT = 'Zero division';
IF denominator = 0 THEN
SIGNAL overflow;
ELSE
SET result = numerator / denominator;
END IF;
END @
The next example just raise an exception, does not wrap a raised one.
BEGIN
SIGNAL SQLSTATE '75002'
SET MESSAGE_TEXT = 'Customer number is not known';
END @
Output:
$ db2 -td@ db2 => BEGIN ... db2 (cont.) => END @ DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL0438N Application raised error or warning with diagnostic text: "Zero division". SQLSTATE=21543 db2 => BEGIN db2 (cont.) => SIGNAL SQLSTATE '75001' db2 (cont.) => SET MESSAGE_TEXT = 'Customer number is not known'; db2 (cont.) => END @ DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL0438N Application raised error or warning with diagnostic text: "Customer number is not known". SQLSTATE=75001
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;
Stata
In Stata, one can trap errors with the capture command.
Without capture, if an error happens in a program, the execution of the current process terminates and the control is returned to the interactive mode. Execution may be terminated by the error or exit commands, or conditionnally using assert or confirm.
Many other commands may terminate the program if some error occurs during execution: for instance regress will return code 2000 if a regressor has only missing values.
Example of usage:
capture confirm file titanium.dta
if _rc {
if _rc==601 {
display "the file does not exist"
}
else {
* all other cases
display "there was an error with return code " _rc
}
}
Similarly, Mata has functions error and exit to terminate execution, as well as assert and asserteq.
Swift
Defining exceptions
Exceptions can be of any type that conforms to the ErrorType
protocol.
enum MyException : ErrorType {
case TerribleException
}
Throw exceptions
A function that throws an exception must be explicitly declared so:
func foo() throws {
throw MyException.TerribleException
}
Catching exceptions
do {
try foo()
} catch MyException.TerribleException { // this can be any pattern
//Catch a specific case of exception
} catch {
//Catch any exception
}
Tcl
package require Tcl 8.5
# Throw
proc e {args} {
error "error message" "error message for stack trace" {errorCode list}
}
# Catch and rethrow
proc f {} {
if {[catch {e 1 2 3 4} errMsg options] != 0} {
return -options $options $errMsg
}
}
f
This creates the stack trace
error message for stack trace (procedure "e" line 1) invoked from within "e 1 2 3 4" (procedure "f" line 2) invoked from within "f"
Transd
#lang transd
mainModule : {
func2: (lambda i Int()
(if (!= i 13)
(textout "OK " i "\n")
(throw "fail\n"))),
func1: (lambda
(textout "before try\n")
(try
(textout "before while\n")
(with n 10
(while (< n 15) (+= n 1)
(func2 n)
)
)
(textout "after while\n")
(catch (report e))
)
(textout "after try\n")
),
_start: (lambda (func1))
}
OUTPUT:
before try before while OK 10 OK 11 OK 12 fail after try
TXR
Here is a complicated exceptions example straight from the manual.
This is a deliberately convoluted way to process input consisting of lines which have the form:
{monkey | gorilla | human} <name>
Some custom exceptions are defined, and arranged into a hierarchy via @(defex) directives. An exception precedence hierarchy is established. A gorilla is a kind of ape, and an ape is a kind of primate. A monkey is a kind of primate, and so is a human.
In the main @(collect) clause, we have a try protect block in which we collect three different cases of primate. For each one, we throw an exception with the primate type symbol, and its name. This is caught in the catch clause as the argument "name". The catch clause performs another pattern match, @kind @name. This match is being applied to exactly the same line of data for which the exception was thrown (backtracking!). Therefore the @kind variable will collect the primate type. However @name already has a binding since it is the argument of the catch. Since it has a value already, that value has to match what is in the data. Of course, it does since it was derived from that data. The data and the variable unify against each other.
@(defex gorilla ape primate)
@(defex monkey primate)
@(defex human primate)
@(collect)
@(try)
@(cases)
gorilla @name
@(throw gorilla name)
@(or)
monkey @name
@(throw monkey name)
@(or)
human @name
@(throw human name)
@(end)@#cases
@(catch primate (name))
@kind @name
@(output)
we have a primate @name of kind @kind
@(end)@#output
@(end)@#try
@(end)@#collect
Sample interactive run. Here the input is typed into standard input from the tty. The output is interleaved with the input, since TXR doesn't reads ahead only as much data as it needs.
$ txr primates.txr - [TTY]human Harry [TTY]gorilla Gordon [OUT]we have a primate Harry of kind human [TTY]monkey Mike [OUT]we have a primate Gordon of kind gorilla [TTY][Ctrl-D/EOF] [OUT]we have a primate Mike of kind monkey
Ursa
Catching exceptions:
try
invalid "this statement will fail"
catch syntaxerror
# console.err is optional here
out "caught an exception" endl console.err
end try
Throwing exceptions:
throw (new ursa.exceptions.exception)
Ursala
In this program fragment, a function named thrower returns the string 'success' if its argument is non-empty, but otherwise raises an exception with the diagnostic message 'epic fail'. (The diagnostic message can also be made to depend on the input.)
#import std
thrower = ~&?/'success'! -[epic fail]-!%
catcher = guard(thrower,---[someone failed]-)
If the exception is not caught, the program terminates immediately and the diagnostic is written to stderr. Alternatively, a calling function or any caller thereof can be defined to catch an exception as shown. The exception handler may inspect and arbitrarily modify the diagnostic message, but normal execution may not be resumed. In this example, the exception handler appends some additional verbiage to the message.
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]
VBA
For historical reasons, Exceptions are called 'Errors' in VBA and VB Classic. VBA inherited several distinct exception handling models, which may be freely mixed and matched. The major limitations are that nested Try/Catch blocks must be constructed by the user, and that the User Defined Labels required for the Catch/Finally blocks may not be reused within a subroutine. For these reasons, it is conventional to only have only 1 Try/Catch block per subroutine.
Throw exceptions
Sub foo1()
err.raise(vbObjectError + 1050)
End Sub
Sub foo2()
Error vbObjectError + 1051
End Sub
Catching exceptions
Sub bar1()
'by convention, a simple handler
On Error GoTo catch
foo1
MsgBox " No Error"
Exit Sub
catch:
'handle all exceptions
MsgBox Err.Number & vbCrLf & Err.Description
Exit Sub
End Sub
Sub bar2()
'a more complex handler, illustrating some of the flexibility of VBA exception handling
On Error GoTo catch
100 foo1
200 foo2
'finally block may be placed anywhere: this is complexity for it's own sake:
GoTo finally
catch:
If Erl = 100 Then
' handle exception at first line: in this case, by ignoring it:
Resume Next
Else
Select Case Err.Number
Case vbObjectError + 1050
' handle exceptions of type 1050
MsgBox "type 1050"
Case vbObjectError + 1051
' handle exceptions of type 1051
MsgBox "type 1051"
Case Else
' handle any type of exception not handled by above catches or line numbers
MsgBox Err.Number & vbCrLf & Err.Description
End Select
Resume finally
End If
finally:
'code here occurs whether or not there was an exception
'block may be placed anywhere
'by convention, often just a drop through to an Exit Sub, rather tnan a code block
GoTo end_try:
end_try:
'by convention, often just a drop through from the catch block
End Sub
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
Wren
Wren doesn't have exceptions as such but we can simulate them by trying to run code which may cause an error in a fiber and then capturing any error that does occur.
Errors can be thrown by calling the Fiber.abort method. The VM will also call this method automatically if a runtime error occurs such as attempting to call a function that doesn't exist.
Here's an example of all this.
var intDiv = Fn.new { |a, b|
if (!(a is Num && a.isInteger) || !(b is Num && b.isInteger)) Fiber.abort("Invalid argument(s).")
if (b == 0) Fiber.abort("Division by zero error.")
if (a == 0) a = a.badMethod()
return (a/b).truncate
}
var a = [ [6, 2], [6, 0], [10, 5], [true, false], [0, 2] ]
for (e in a) {
var d
var f = Fiber.new { d = intDiv.call(e[0], e[1]) }
f.try()
if (f.error) {
System.print("Caught %(f.error)")
} else {
System.print("%(e[0]) / %(e[1]) = %(d)")
}
}
- Output:
6 / 2 = 3 Caught Division by zero error. 10 / 5 = 2 Caught Invalid argument(s). Caught Num does not implement 'badMethod()'.
zkl
try{ throw(Exception.BadDay) }
catch { println(__exception," was thrown") }
fallthrough { println("No exception was thrown") }
println("OK");
- Output:
BadDay(I'm having a bad day) was thrown OK
If you want "finally" functionality, use onExit or onExitBlock:
fcn f(b){
try{
onExitBlock("Exit code".println);
if (b) throw(Exception.BadDay)
}
catch{ println(__exception," was thrown") }
fallthrough{ println("No exception was thrown") }
println("OK");
}
f(False); println("--------");
f(True);
- Output:
Exit code No exception was thrown OK -------- Exit code BadDay(I'm having a bad day) was thrown OK
Zig
const std = @import("std");
// To replace exceptions, Zig has error enums to handle error states.
pub fn main() !void {
// writing to stdout as file descriptor might fail,
// if we are a child process and the parent process has closed it
const stdout_wr = std.io.getStdOut().writer();
try stdout_wr.writeAll("a");
// Above code is identical to
stdout_wr.writeAll("a") catch |err| return err;
stdout_wr.writeAll("a") catch |err| {
// usually std streams are leaked and the Kernel cleans them up
var stdin = std.io.getStdIn();
var stderr = std.io.getStdErr();
stdin.close();
stderr.close();
return err;
};
}
- Programming Tasks
- Control Structures
- Euphoria/Omit
- M4/Omit
- Retro/Omit
- 11l
- 8086 Assembly
- Ada
- Aikido
- Aime
- ALGOL 68
- AppleScript
- AutoHotkey
- BBC BASIC
- Blz
- Bracmat
- C
- C sharp
- C++
- Clojure
- ColdFusion
- Common Lisp
- D
- Delphi
- Dyalect
- DWScript
- Déjà Vu
- E
- Elena
- Erlang
- Factor
- Fancy
- Fantom
- Forth
- FreeBASIC
- Gambas
- Go
- Haskell
- HolyC
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Langur
- Lasso
- Lingo
- Logo
- Logtalk
- Lua
- M2000 Interpreter
- Make
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Modula-3
- MOO
- Nanoquery
- Nemerle
- NetRexx
- Nim
- Objective-C
- OCaml
- Oforth
- Oz
- PARI/GP
- PARI/GP examples needing attention
- Examples needing attention
- Pascal
- Perl
- Phix
- Phix/basics
- PHL
- PHP
- PicoLisp
- PL/I
- PL/pgSQL
- Pop11
- PowerShell
- Prolog
- PureBasic
- Python
- Quackery
- R
- Racket
- Raku
- Raven
- REXX
- Ring
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- Sidef
- Slate
- Slate examples needing attention
- Smalltalk
- SQL PL
- Standard ML
- Stata
- Swift
- Tcl
- Transd
- TXR
- Ursa
- Ursala
- V
- VBA
- Visual Basic .NET
- Wren
- Zkl
- Zig
- Pages with too many expensive parser function calls