LMD ScriptPack Guide
PasScript provides true exceptions support through try/except, try/finally and raise statements. The raise statement can be used to throw exceptions, like this:
if X > 10 then
raise Exception.Create('X is too big');
Note, that here Exception.Create(...) is just an expression that creates an instance of the exception. So, to really use the raise statement, it is required to add imported VCL unit(s) to the script-control to allow script-code to use exception types (Exception in this case). Otherwise, you will get "Undeclared identifier" run-time error.
Your program can use try/except statement to catch raised exceptions and execute error handling code. Just like in Delphi the except part of the statement can be in a simple or complex form. The simple form example:
try
DoSomething;
except
ShowMessage('Error has occurred.');
end;
The except part in this form will catch all possible exception. The example of complex except form:
try
DoSomething;
except
on E: EArgumentException do
ShowMessage('Invalid argument');
on E: EOutOfMemory do
ShowMessage('Out of memory');
else
ShowMessage('Other error.');
end;
Any number of on/do blocks can be specified. An on/do block catch only exception of the specified class (or a subclass of it). The else block catches all other exceptions. The else block is optional. Note, that empty else block also catches all possible exceptions, however, if the else block is omit, then all not caught exceptions will be thrown away from the current try statement.
The variable name (E in the example) is optional, but, if specified, the variable becomes accessible within the corresponding on/do block and holds the reference to the current exception instance:
try
DoSomething;
except
on E: EArgumentException do
LogMessage('Error: ' + E.Message);
end;
Normally, if the exception is caught by except handler, it will not be re-raised implicitly to parent statements. If you need to re-raise the exception, you can use the raise statement without arguments:
try
DoSomething;
except
ShowMessage('Error');
raise;
end;
This form of the raise statement is only allowed inside except handler. The run-time error will occurs otherwise.
Your program can use the try/finally statement to guarantee execution of the finalization code in both cases: when error occurred and when it is not:
obj := TMyObject.Create;
try
obj.DoSomething;
finally
obj.Free;
end;
The obj instance, created in above example will be freed in any case, even if DoSomething will raise an exception. try/finally statement always implicitly re-raise the current exception, so it can be caught by parent statements.
If Break, Continue or Exit intrinsic functions are used inside the try/finally block and leads outside of the try/finally, the finally statements will be also executed:
for i := 0 to 10 do
begin
try
Break;
finally
ShowMessage('In finally');
end;
end;
It is illegal to use Break, Continue or Exit intrinsic functions inside the finally itself; run-time error will be raised:
for i := 0 to 10 do
begin
try
DoSomething;
finally
Break; // Illegal!
end;
end;