Exceptions/Catch an exception thrown in a nested call: Difference between revisions
Exceptions/Catch an exception thrown in a nested call (view source)
Revision as of 10:46, 27 August 2022
, 1 year agosyntax highlighting fixup automation
(fix code and add output) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 18:
=={{header|11l}}==
{{trans|Python}}
<
T U1 {}
Line 37:
print(‘Function foo caught exception U0’)
foo()</
{{out}}
Line 46:
=={{header|Ada}}==
<
procedure Exceptions_From_Nested_Calls is
Line 76:
Foo;
end loop;
end Exceptions_From_Nested_Calls;</
{{out}}
<pre>
Line 88:
=={{header|Aime}}==
<
baz(integer i)
{
Line 128:
return 0;
}</
{{out}}
<pre>Exception `U0' thrown
Line 149:
c.f. [[Exceptions#ALGOL_68|ALGOL 68 Exceptions]] for more details.
<
INT value,
STRUCT(
Line 204:
FI;
foo</
{{out}}
<pre>
Line 222:
{{works with|Dyalog APL}}
<
⍝ Traps (exceptions) are just numbers
⍝ 500-999 are reserved for the user
Line 242:
⎕SIGNAL U0 U1[i]
∇
:EndNamespace</
{{out}}
Line 260:
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/>
When this program is run, the first exception (U0) is raised, and caught by the try-catch section. This causes a Message Box containing the text "An exception was raised: First Exception" to be displayed by the script. The second exception is not caught, generating a runtime error.
<
global U1 := Exception("Second Exception")
Line 283:
else if ( calls = 2 )
throw U1
}</
The runtime error:
<pre>Error: Second Exception
Line 305:
The global ErrorLevel keeps track of the last error.
Here is one way to keep track of nested errors:
<syntaxhighlight lang="autohotkey">foo()
Return
Line 334:
ErrorLevel .= "U0"
Return 1
}</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
U0& = 123
U1& = 124
Line 364:
ENDCASE
ENDPROC
</syntaxhighlight>
{{out}} (the second message is output by the default error handler):
<pre>Exception U0 caught in foo
Line 387:
U0 and U1 are boring for debugging purposes. Added something to help with that.
<
#include <stdlib.h>
Line 508:
</syntaxhighlight>
{{out}}
<pre>Foo entering bar.
Line 524:
This example will first catch U0 and print "U0 Caught" to the console when it does. The uncaught U1 exception will then cause the program to terminate and print the type of the exception, location of the error, and the stack.
<
class Exceptions
{
Line 555:
foo();
}
}</
{{out}}
Line 573:
aborting the task, typically with an error message.
<
class U0 {};
class U1 {};
Line 600:
std::cout<< "Should never get here!\n";
return 0;
}</
Result:
Line 610:
=={{header|Clojure}}==
<
(def U1 (ex-info "U1" {}))
Line 626:
(defn -main [& args]
(foo))</
{{output}}
Line 646:
=={{header|Common Lisp}}==
<
(define-condition user-condition-2 (error) ())
Line 663:
(trace foo bar baz)
(foo)</
{{out}} (the numbered lines are output from <code>trace</code>):
<
1: (BAR USER-CONDITION-1)
2: (BAZ USER-CONDITION-1)
foo: Caught: Condition USER-CONDITION-1 was signalled.
1: (BAR USER-CONDITION-2)
2: (BAZ USER-CONDITION-2)</
At this point, the debugger (if any) is invoked
Line 678:
=={{header|Crystal}}==
<
end
Line 703:
end
foo</
<pre>
Line 720:
First exception will be caught and message will be displayed,
second will be caught by default exception handler.
<
this() @safe pure nothrow { super("U0 error message"); }
}
Line 750:
void main() {
foo;
}</
{{out}}
<pre>test.U1(at)test.d(8): U1 error message
Line 762:
=={{header|Delphi}}==
{{Trans|D}}
<
{$APPTYPE CONSOLE}
Line 804:
begin
Foo;
end.</
{{out}}
Line 816:
{{Trans|D}}
First exception will be caught and message will be displayed, second will be caught by default exception handler.
<
type Exception2 = class (Exception) end;
Line 845:
end;
Foo;</
Result:
<pre>Exception1 caught
Line 852:
=={{header|Dyalect}}==
<
func baz() {
Line 879:
}
foo()</
{{out}}
Line 887:
=={{header|EchoLisp}}==
<
(define (foo)
(for ((i 2))
Line 909:
"U0 raised" catched
👓 error: U1 not catched
</syntaxhighlight>
=={{header|EGL}}==
{{incorrect|EGL|calls to bar() from foo should be equivalent. Second call can't catch anything.}}
<
end
Line 947:
end
end
end</
{{out}}
Line 959:
A file called main.e:
<
inherit EXCEPTIONS
Line 996:
end
end
end</
{{out}}
Line 1,028:
=={{header|Elena}}==
ELENA 5.0 :
<
class U0 : Exception
Line 1,080:
{
Exceptions.foo()
}</
{{out}}
<pre>
Line 1,097:
=={{header|Elixir}}==
<
defmodule U1, do: defexception [:message]
Line 1,117:
end
ExceptionsTest.foo</
{{out}}
Line 1,132:
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( exceptions_catch ).
Line 1,152:
end.
</syntaxhighlight>
{{out}}
<pre>
Line 1,165:
=={{header|Factor}}==
<
IN: rosetta-code.nested-exceptions
Line 1,185:
] twice ;
foo</
{{out}}
<pre>
Line 1,209:
=={{header|Fantom}}==
<
const class U0 : Err
{
Line 1,258:
}
}
</syntaxhighlight>
{{out}}
Line 1,289:
=={{header|FreeBASIC}}==
FreeBASIC does not support exceptions or the Try/Catch/Finally statement, as such. However, you can use the Err() function, together with an If (or Switch) statement, to provide somewhat similar functionality:
<
Enum ErrorTypes
Line 1,336:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,354:
The solution here is to define a wrapper, or proxy function, called try.
Function foo calls bar indirectly through try.
<
//
// As all Go programmers should know, the Go authors are sharply critical of
Line 1,456:
}
trace("complete")
}</
{{out}}
<pre>
Line 1,494:
</pre>
A simpler example, closer to the task description:
<
import "fmt"
Line 1,552:
foo()
fmt.Println("No panic")
}</
[http://play.golang.org/p/X2pa8zE1Ce Run in Go Playground].
{{out}}
Line 1,564:
=={{header|Haskell}}==
<
import Control.Monad.Trans (lift)
Line 1,601:
case result of
Left e -> putStrLn ("Caught error at top level: " ++ show e)
Right v -> putStrLn ("Return value: " ++ show v)</
{{out}}
Line 1,622:
not found in languages that natively support exceptions.</i>
<
class U0 : Exception()
Line 1,666:
initial U0().throw("First exception")
U1().throw("Second exception")
end</
{{out}}
Line 1,685:
=={{header|Io}}==
<
U1 := Exception clone
Line 1,704:
)
foo</
{{out}}
<pre>foo caught U0
Line 1,719:
J leaves most of the implementation of exceptions to the programmer, so:
<
smoutput 'main'
try. foo ''
Line 1,740:
smoutput ' baz'
type_jthrow_=: 'U',":y throw.
)</
'''Example use:'''
<
main
foo
Line 1,751:
bar
baz
main caught U1</
=={{header|Java}}==
Line 1,759:
(or a superclass thereof), unless they are unchecked exceptions
(subclasses of <code>RuntimeException</code> or <code>Error</code>):
<
class U1 extends Exception { }
Line 1,787:
foo();
}
}</
{{out}}
<pre>
Line 1,814:
The <code>callee.name</code> property, and the <code>catch(e if ...)</code> statement are Mozilla JavaScript extensions.
<
U.prototype.toString = function(){return this.className;}
Line 1,848:
}
foo();</
{{out}} from [[Rhino]]:
<pre>caught exception U0
Line 1,858:
=={{header|jq}}==
{{works with|jq|>1.4}}
<
def baz(n):
if n==0 then error("U0")
Line 1,871:
(try bar(1) catch if . == "U0" then "We caught U0" else error(.) end);
foo</
{{out}}
$ jq -n -f Catch_an_exception_thrown_in_a_nested_call.jq
Line 1,880:
{{works with|Julia|0.6}}
<
struct U1 <: Exception end
Line 1,907:
end
foo()</
{{out}}
Line 1,917:
=={{header|Kotlin}}==
<
class U0 : Throwable("U0 occurred")
Line 1,945:
fun main(args: Array<String>) {
foo()
}</
{{out}}
Line 1,964:
Prior to 0.7, you would use .err instead of _err for an implicit exception variable.
<
val .U1 = h{"msg": "U1"}
Line 1,981:
}
.foo()</
{{out}}
Line 1,992:
but we can easily add one like so.
<
local(
gb = givenblock,
Line 2,031:
var(bazzed) ? fail('U1') | $bazzed = true
fail('U0')
}</
{{out}}
Line 2,054:
=={{header|Lua}}==
<
function baz()
if baz_counter==1 then
Line 2,087:
foo()
</syntaxhighlight>
output:
<pre>lua: errorexample.lua:31: U1
Line 2,098:
=={{header|Maple}}==
<
if ( which = 0 ) then
error "U0";
Line 2,120:
end proc:
foo();</
{{out}}
<syntaxhighlight lang
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
bar[i_] := baz[i];
Line 2,131:
baz[i_] := Switch[i,
1, Throw["Exception U0 in baz"];,
2, Throw["Exception U1 in baz"];]</
Output:
<pre> foo[]
Line 2,137:
=={{header|MATLAB}} / {{header|Octave}}==
<
function foo()
Line 2,167:
foo();
end</
{{out}}
<
message: [1x177 char]
identifier: 'BAZ:U0'
Line 2,178:
Error in ==> exceptionsCatchNestedCall at 29
foo();</
=={{header|Nemerle}}==
<
using System.Console;
Line 2,231:
}
}
}</
{{out}}
<pre>Exception U0 caught.
Line 2,241:
=={{header|Nim}}==
<
type U1 = object of Exception
Line 2,258:
echo "Function foo caught exception U0"
foo()</
{{out}}
<pre>Function foo caught exception U0
Line 2,270:
=={{header|Objective-C}}==
<
@end
@interface U1 : NSObject { }
Line 2,312:
}
return 0;
}</
{{out}}
<pre>
Line 2,321:
=={{header|OCaml}}==
Exceptions are used everywhere in OCaml, they are easy to write, and they are cheap.
<
exception U1
Line 2,337:
done
let () = foo ()</
{{out}}
<pre>
Line 2,346:
=={{header|Oforth}}==
<
Exception Class new: U1
Line 2,356:
try: e [ 0 bar ] when: [ e isKindOf(U0) ifTrue: [ "Catched" .cr ] else: [ e throw ] ]
try: e [ 1 bar ] when: [ e isKindOf(U0) ifTrue: [ "Catched" .cr ] else: [ e throw ] ]
"Done" . ;</
{{out}}
Line 2,369:
Exceptions are caught by pattern matching.
<
proc {Foo}
for I in 1..2 do
Line 2,389:
end
in
{Foo}</
{{out}}
Line 2,404:
=={{header|PARI/GP}}==
<
U0() = error("x = ", 1, " should not happen!");
Line 2,410:
baz(x) = if(x==1, U0(), x==2, U1());x;
bar() = baz(call++);
foo() = if(!call, iferr(bar(), E, printf("Caught exception, call=%d",call)), bar())</
Output 1. call to foo():<pre>Caught exception, call=1</pre>
Line 2,432:
=={{header|Perl}}==
Note: Both exceptions are caught and one is re-raised rather than only one being caught.
<
foreach (0..1) {
eval { bar($_) };
Line 2,449:
}
foo();</
{{out}}
<pre>
Line 2,463:
As per the discussion for Go, I should say that "bar(); bar();" cannot work - if you catch an exception from the first call,
control resumes within the catch handler, with no way to invoke that second bar(). But a simple loop does the trick.
<!--<
<span style="color: #008080;">constant</span> <span style="color: #000000;">U0</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0<span style="color: #0000FF;">,</span>
<span style="color: #000000;">U1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
Line 2,499:
<span style="color: #000000;">foo<span style="color: #0000FF;">(<span style="color: #0000FF;">)
<!--</
{{out}}
<pre>
Line 2,519:
=={{header|PicoLisp}}==
<
(for Tag '(U0 U1)
(catch 'U0
Line 2,531:
(mapc trace '(foo bar baz))
(foo)</
{{out}}
<pre> foo :
Line 2,543:
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
/* Exceptions: Catch an exception thrown in a nested call */
test: proc options (main);
Line 2,574:
m = foo();
end test;
</syntaxhighlight>
DESCRIPTION OF EXECUTION:
Line 2,606:
There is no extra syntax to add to functions and/or methods such as ''bar'',
to say what exceptions they may raise or pass through them:
<
class U1(Exception): pass
Line 2,622:
raise U1 if i else U0
foo()</
{{out}}
<pre>
Line 2,647:
=={{header|Quackery}}==
<
[ this ] is U1
Line 2,669:
message release
drop ]
else [ drop bail ] ] ] ] is foo</
{{out}}
Line 2,709:
in your own environment.
See ?new.env and ?get.
<syntaxhighlight lang="r">
number_of_calls_to_baz <- 0
Line 2,725:
stop(e)
}
</syntaxhighlight>
Example Usage:
<syntaxhighlight lang="r">
foo() # Error: U0
traceback()
</syntaxhighlight>
{{out}}
<pre>
Line 2,742:
=={{header|Racket}}==
<
#lang racket
Line 2,762:
(foo)
</syntaxhighlight>
{{out}}
<
Function foo caught exception U0
. . failed 1
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku"
for 0..1 -> $i {
bar $i;
Line 2,785:
sub baz($i) { die "U$i" }
foo;</
{{out}}
<pre>Function foo caught exception U0
Line 2,798:
<br>This type of exception handling (in REXX) has its limitation
(the label is known global to the program, but not to external subroutines).
<
call foo /*invoke the FOO function (below). */
say 'The REXX mainline program has completed.' /*indicate that Elroy was here. */
Line 2,819:
/* [↓] this U0 subroutine is ignored.*/
U0: return -1 /*handle exception if not caught. */
U1: return -1 /* " " " " " */</
'''output'''
<pre>
Line 2,827:
=={{header|Ruby}}==
<
2.times do |i|
begin
Line 2,849:
class U1 < StandardError; end
foo</
The first call to foo causes the U0 exception. It gets rescued.
The second call results in a U1 exception which is not rescued,
Line 2,865:
=={{header|Rust}}==
Rust has panics, which are similar to exceptions in that they default to unwinding the stack and the unwinding can be caught. However, panics can be configured to simply abort the program and thus cannot be guaranteed to be catchable. Panics should only be used for situations which are truly unexpected. It is prefered to return an Option or Result when a function can fail. <code>Result<T, U></code> is an enum (or sum type) with variants <code>Ok(T)</code> and <code>Err(U)</code>, representing a success value or failure value. <code>main</code> can return a Result, in which case the debug representation of the error will be shown.
<
enum U {
U0(i32),
Line 2,896:
fn main() -> Result<(), U> {
foo()
}</
{{out}}
<pre>Caught U0 in foo: 42
Line 2,903:
=={{header|Scala}}==
{{libheader|Scala}}
<
class U0 extends Exception
class U1 extends Exception
Line 2,922:
foo
}
</syntaxhighlight>
Exception U0 is caught, exception U1 is caught and re-thrown.
Program execution is terminated as the U1 exception is not caught
Line 2,931:
is not [http://seed7.sourceforge.net/manual/errors.htm#Handlers handled]
the program is terminated and a [http://seed7.sourceforge.net/manual/errors.htm#Stack_trace stack trace] is written.
<
const EXCEPTION: U0 is enumlit;
Line 2,966:
begin
foo;
end func;</
{{out}}
Line 2,984:
=={{header|Sidef}}==
<
func bar(i) { baz(i) };
Line 2,997:
}
foo();</
{{out}}
<pre>
Line 3,006:
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
Exception subclass: #U0.
Exception subclass: #U1.
Line 3,032:
"Thirds time's a charm..."]
]
</syntaxhighlight>
Running the code:
<syntaxhighlight lang="smalltalk">
st> Foo new foo
'Call to bar was aborted by exception U0'
Line 3,047:
UndefinedObject>>executeStatements (a String:1)
nil
</syntaxhighlight>
Explanation:<br/>
Line 3,069:
=={{header|Swift}}==
{{works with|Swift|2.x+}}
<
case U0
case U1
Line 3,096:
}
try foo()</
{{out}}
<pre>
Line 3,107:
{{works with|Tcl|8.5}}
<
proc foo {} {
Line 3,132:
foo
foo</
{{out}}
<pre>$ tclsh85 exceptions.tcl
Line 3,149:
=={{header|TXR}}==
<
@(defex u1)
@(define baz (x))
Line 3,176:
@ (end)
@(end)
@(foo)</
{{out|Run}}
Line 3,192:
if baz raises an exception.
The exception is caught or not by foo.
<
baz =
Line 3,210:
guard(
:/'foo received this result from normal termination of bar:'+ bar,
'U0'?=z/~& :/'foo caught an exception with this error message:')</
Note that the definition of bar includes no conditional (?) or exception
handling operators, and is written without regard for any exceptions.
Line 3,230:
=={{header|Visual Basic .NET}}==
<
Inherits Exception
End Class
Line 3,266:
End If
End Sub
End Module</
Control passes to the Catch block after U0 is thrown, and so the second call to Bar() is not made.
Line 3,275:
To prevent this, a loop can be used to run the entire Try statement twice:
<
For i = 1 To 2
Try
Line 3,283:
End Try
Next
End Sub</
{{out}}
Line 3,298:
We can use that approach here, re-throwing the second (uncaught) exception so that it terminates the script.
<
var U1 = "U1"
Line 3,325:
}
foo.call()</
{{out}}
Line 3,336:
=={{header|zkl}}==
<
class U1(Exception.Exception){fcn init{Exception.init("U1")}}
Line 3,342:
fcn bar(e){baz(e)}
fcn baz(e){throw(e)}
foo()</
{{out}}
<pre>
|