Exceptions/Catch an exception thrown in a nested call: Difference between revisions

(Added uBasic/4tH version)
(15 intermediate revisions by 8 users not shown)
Line 23:
F baz(i)
I i == 0
X.throw U0()
E
X.throw U1()
 
F bar(i)
Line 218:
'''par''' clause, then all parallel the threads are terminated and the
program continues in the parent thread. <!-- example needed -->
 
=={{header|Amazing Hopper}}==
<p>Hopper has a basic "try/catch" handling, and must be handled manually. Only one exception will be raised.</p>
<p>VERSION 1: </p>
<syntaxhighlight lang="c">
#include <jambo.h>
 
Main
e=0, se=""
Try
Gosub 'Foo'
Catch (e)
Get msg exception, and Move to 'se'
Printnl ("+-MAIN-FOO CALL Error: ",e, " : ", se )
Finish
End
 
Subrutines
 
Define ' Foo '
Gosub ' Bar '
Return
 
Define ' Bar '
Set '0', Gosub ' Biz '
Set '1', Gosub ' Biz '
Return
 
Define ' Biz, x '
a=0, b=0
If ( x )
Let ' b:=Sqrt(-1) '
Nan( a ) do{ Raise (1000,"\n+----Func BIZ: NaN!") }
Else
#( a=log(-1) + log(-1) )
Nan( a ) do{ Raise (1001,"\n+----Func BIZ: NaN!") }
End If
Printnl ' "a = ", a, " b = ", b '
 
Return
</syntaxhighlight>
{{out}}
<pre>
+-MAIN-FOO CALL Error: 1001 :
+----Func BIZ: NaN!
</pre>
<p>VERSION 2: </p>
<syntaxhighlight lang="c">
#include <jambo.h>
 
Main
e=0, se=""
Try
Gosub 'Foo'
Catch (e)
Get msg exception, and Move to 'se'
Printnl ("+-MAIN Error: ",e, " : ", se )
Finish
End
 
Subrutines
 
/*
This "Try" is not considered nested, then, it is necessary
to capture the error and raise the error
*/
Define ' Foo '
Try
Gosub ' Bar '
Catch (e)
Get msg exception, and Move to 'se'
Free try // absolutly nessesary in this chase!
Raise (e, Cat ("\n+--FUNC FOO: ", se) )
Finish
Return
 
Define ' Bar '
Try
Set '0', Gosub ' Biz '
Set '1', Gosub ' Biz '
Catch(e)
Get msg exception, and Move to 'se'
Free try // absolutly nessesary in this chase!
Raise (e, Cat ("\n+---FUNC BAR: ", se) )
Finish
 
Return
 
Define ' Biz, x '
a=0, b=0
If ( x )
Let ' b:=Sqrt(-1) '
Nan( a ) do{ Raise (1000,"\n+----Func BIZ: NaN!") }
Else
#( a=log(-1) + log(-1) )
Nan( a ) do{ Raise (1001,"\n+----Func BIZ: NaN!") }
End If
Printnl ' "a = ", a, " b = ", b '
 
Return
</syntaxhighlight>
{{out}}
<pre>
+-MAIN Error: 1001 :
+--FUNC FOO:
+---FUNC BAR:
+----Func BIZ: NaN!
</pre>
 
=={{header|APL}}==
Line 1,027 ⟶ 1,137:
 
=={{header|Elena}}==
ELENA 56.0x :
<syntaxhighlight lang="elena">import extensions;
class U0 : Exception
{
constructor new()
<= super new("U0 exception");
}
class U1 : Exception
{
constructor new()
<= super new("U1 exception");
}
singleton Exceptions
{
static int i;
bar()
<= baz();
baz()
{
if (i == 0)
{
U0.raise()
}
else
{
U1.raise()
}
}
foo()
{
for(i := 0,; i < 2,; i +:= i + 1)
{
try
{
self.bar()
}
catch(U0 e)
{
console.printLine("U0 Caught")
}
}
}
}
Line 1,084 ⟶ 1,194:
<pre>
U0 Caught
U1 exception
mytest'U1#class
Call stack:
sandbox'$private'Exceptions.baz[1]:sandbox.l(30)
system'Exception#class.new$system'LiteralValue[1]:exceptions.l(124)
sandbox'$private'Exceptions.foo[1]:sandbox.l(40)
system'Exception#class.new[0]:exceptions.l(128)
sandbox'program.function:#invoke:sandbox.l(52)
mytest'Exceptions.baz[0]:test.l(21)
system'$private'entry.function:#invoke:app.l(5)
mytest'Exceptions.bar[0]:test.l(12)
system'$private'entrySymbol#sym:app.l(23)
mytest'Exceptions.foo[0]:test.l(30)
 
mytest'program.eval[0]:test.l(45)
Aborted:ffffffff
system'#inline1AB.start[1]:win32_app.l(35)
system'startUp(1)
</pre>
 
Line 1,961 ⟶ 2,070:
 
There is no explicit try block. A catch implicitly wraps the instructions preceding it within a block into a try block.
 
Prior to 0.7, you would use .err instead of _err for an implicit exception variable.
 
<syntaxhighlight lang="langur">val .U0 = h{"msg": "U0"}
val .U1 = h{"msg": "U1"}
 
val .baz = ffn(.i) throw if(.i==0: .U0; .U1)
val .bar = ffn(.i) .baz(.i)
 
val .foo = fimpure fn() {
for .i in [0, 1] {
.bar(.i)
catch {
if _err["'msg"] == .U0["'msg"] {
writeln "caught .U0 in .foo()"
} else {
Line 1,983 ⟶ 2,090:
}
 
.foo()</syntaxhighlight>
</syntaxhighlight>
 
{{out}}
Line 2,986 ⟶ 3,094:
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func baz(i) { die "U#{i}" };
func bar(i) { baz(i) };
 
func foo {
[0, 1].each { |i|
try { bar(i) }
catch { |_, msg|
msg ~~ /^U0/  ? say "Function foo() caught exception U0"
 : die msg; # re-raise the exception
};
}
}
 
foo();</syntaxhighlight>
{{out}}
<pre>
Line 3,202 ⟶ 3,310:
If x = u ' catch U0
If Try(_bar(x)) Then ' try to execute bar
Print "FunctionProcedure foo caught exception U0"
EndIf ' catch exception and write msg
Else ' don't catch other exceptions
Line 3,220 ⟶ 3,328:
Return</syntaxhighlight>
{{Out}}
<pre>FunctionProcedure foo caught exception U0
 
Q Exception raised, 16092559880829058:136</pre>
 
=={{header|Ursala}}==
Foo calls bar, and bar calls baz. Normal termination of bar is bypassed
Line 3,333 ⟶ 3,442:
 
We can use that approach here, re-throwing the second (uncaught) exception so that it terminates the script.
<syntaxhighlight lang="ecmascriptwren">var U0 = "U0"
var U1 = "U1"
 
Line 3,368 ⟶ 3,477:
[./exceptions_nested line 23] in new(_) block argument
[./exceptions_nested line 28] in (script)
</pre>
 
=={{header|XPL0}}==
The obvious solution is to simply do the catch error handling at the
point where the error is detected. However, XPL0's Restart intrinsic can
be used to do something similar to C++'s catch operation. This technique
avoids having to pass an error condition back up through several levels
of function calls. (Technically, these functions are actually procedures
because they don't return a value, but XPL0 doesn't enforce the
distinction.)
<syntaxhighlight lang "XPL0">func U0; \Exception caused by square root of negative value
real X;
X:= Sqrt(-42.);
 
func U1; \Exception caused by opening a non-existent file for input
int F;
F:= FOpen("unobtainium.txt", 0);
 
func Baz;
int CallNo;
[CallNo:= [1]; \static-like variable
if CallNo(0) = 1 then \first time Baz is called
[CallNo(0):= 2;
Text(0, "Calling U0^m^j");
Trap(false); \turn off error trapping to prevent program abort
U0;
Restart;
]
else \second time Baz is called
[Text(0, "Calling U1^m^j");
U1; \error trapping is still disabled
];
];
 
func Bar;
Baz;
 
func Foo;
Bar;
 
int Err;
[Err:= GetErr; \get the exception error after the program is restarted
if Err then \reading GetErr resets any error number to 0, = no error
[Text(0, "Error "); IntOut(0, Err); Text(0, " detected^m^j")];
Foo;
Text(0, "Finished^m^j");
] \second exception is pending, and it will be displayed
</syntaxhighlight>
{{out}}
<pre>
Calling U0
Error 10 detected
Calling U1
Finished
 
RUN-TIME ERROR 3: I/O
</pre>
 
890

edits