LMD ScriptPack Guide


Exception Handling Statements


Raise statement

 

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.

 

Try/except statement

 

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.

 

Try/finally statement

 

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;