Try Block Statements
A try
statement surrounds a protected block that receives special treatment when an Exception occurs during its execution, whether in the try
block itself, or any other code that is called from within the block.
Two types of handler sections can be provided at the end of the try
block, to determine what happens when an exception occurs: finally
and except
. Any individual try
block can specify either or both of these sections, and in either order.
Finally Sections
A finally
section can provide code that will always execute, whether an exception occurs or not. Recall that normally an exception terminates all execution flow on the current thread, terminating the current method, and its callers, until the the point where the exception is handled. Code inside the finally
section is an exception (pardon the pun) to that.
Finally sections are useful for cleanup code that must be ensured to run even in case of exceptions – for example to close unmanaged resources such as an open file:
try
DoSoemthing;
MaybeThrowsAnException;
DoSomethingMore;
finally
Cleanup;
end;
AndDoYetMore;
In this example, Cleanup
would always be called, even if MaybeThrowsAnException
indeed does throw an exception. DoSomethingMore
and AndDoYetMore
of course are not.
Except Sections
By contrast, an except
section will only run if an exception occurs and it will handle (or "catch") the exception, so that execution flow will continue normally as if nothing happened:
try
DoSoemthing;
MaybeThrowsAnException;
DoSomethingMore;
except
writeLn("An error occurred");
end;
AndDoYetMore;
In this example, the writeLn
would only be called if MaybeThrowsAnException
(or any other code in the try
block) does throw an exception. Since the exception is then considered handled, AndDoYetMore
would be called as well.
Inside the except
block, one or more on
/do
clauses can be provided to filter for specific exceptions. Note that the except
block can either contain regular code statements or on
/do
clauses, but not mix both:
try
DoSoemthing;
MaybeThrowsAnException;
DoSomethingMore;
except
on E: FileNotFoundException do
writeLn("Can't load that file. moving on without");
end;
AndDoYetMore;
In this case, the except
block only handles the exception if it is of the right type. Any other exception will continue to bubble up the call stack.
Multiple on
/do
clauses are allowed, and an optional where
condition can be used to filter exceptions on criteria other than their type. Note that only the first clause that matches a given exception is executed, and the exception is only considered handled if it did match one of the clauses:
try
DoSoemthing;
MaybeThrowsAnException;
DoSomethingMore;
except
on E: FileNotFoundException do
writeLn("Can't load that file. moving on without");
on E: HttpException where E.Code = 404 do
writeLn("Can't load that webpage. moving on without");
on E: HttpException do
writeLn("Different web error");
end;
AndDoYetMore;
Here, both FileNotFoundException
and HttpException
types are caught, with a different handler being run depending on the error code in the HttpException
. Any other exception will continue uncaught.
Re-raising Exceptions
Inside an except
section, code may decide to not handle the exception after all, and to re-raise it. This can be done by using the raise
Statement or a raise
Expression on its own, without specifying a new exception expression:
except
on E: FileNotFoundException do
if FileName = "ReallyImortant.txt" then
raise;
writeLn("Can't load that file, but it seems unimportant...");
end;
Note that using raise
without an expression will let the current exception continue untouched, preserving all its information, including the original call stack. Using raise E
or even raise new Exception(...)
would instead raise the (or a new) exception fresh, losing the history.
Combining finally
and except
Both finally
and except
sections can be combined within a single trt
block. In case of an exception, they will be run in the order they have been specified:
try
DoSoemthing;
MaybeThrowsAnException;
DoSomethingMore;
finally
Cleanup;
except
writeLn("An error occurred, but we cleaned up fine.");
end;
AndDoYetMore;
See Also
- Exception Handling
Exception
base typeraise
Statements andraise
Expressions