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

Content added Content deleted
(Added XPL0 example.)
Line 3,369: Line 3,369:
[./exceptions_nested line 23] in new(_) block argument
[./exceptions_nested line 23] in new(_) block argument
[./exceptions_nested line 28] in (script)
[./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");
]</syntaxhighlight>
{{out}}
<pre>
Calling U0
Error 10 detected
Calling U1
Finished

RUN-TIME ERROR 3: I/O
</pre>
</pre>