The .NET framework supports exceptions. When a piece of code
generates an error condition, the system raises an exception. By
default, this will cause the program to terminate with a diagnostic message.
However, if the code lies within a TRY block then
it is possible to respond to the error and continue
execution. The same is true if the error occurs within a subprogram that
has been called from within a TRY block.
Raising an exception is an expensive process, so you should design your
code so that exceptions are only raised under genuine error
conditions. The practise of using exceptions as a device to perform
non-local jumps should be avoided. In contrast, entering or leaving a
TRY block has only a small overhead unless and until an exception is
Here is a simple example of code containing a TRY block:
STOP 'Here we go'
PRINT*,'This should never print'
PRINT*,'In CATCH block'
PRINT*,'In FINALLY block'
A TRY block is terminated by ENDTRY. The TRY statements in the block are
followed by a CATCH block. A CATCH block is terminated by the beginning of
another CATCH block or by FINALLY or by ENDTRY. A single
FINALLY block (if present) is written at the end and is terminated by
ENDTRY. Statements in a CATCH block are only executed when the
corresponding exception is raised by one of the
TRY statements at which point control is transferred to the CATCH
block and any remaining statements in the TRY block are skipped.
The FINALLY block is always executed so terminating TRY statements
that must not be skipped (when an exception is raised) should be
written in the FINALLY block.
A STOP statement that has a message string raises an exception.
Consequently the program above produces the following output:
In CATCH block
In FINALLY block
If the STOP statement is removed from the program an exception is not
raised and the output is:
This should never print
In FINALLY block
Although this is an artificial example, it illustrates the fact that, when an
exception is raised, the remaining TRY statements (before CATCH or
FINALLY) are abandoned and control is passed to the CATCH block. In either
case (whether or not an exception is raised) statements in a FINALLY
block are then executed.
CATCH takes an argument that specifies the exception that is to be handled
by the block. The system matches the kind of exception that has
been raised with the argument of the CATCH block. The
exception can match exactly (as in this example). Alternativley you
can use a base class (e.g. System.Exception) when declaring
the variable (myexception) in order to catch all exceptions that are
members of the base class. See the .NET documentation for information
about the relevant class members.
When an exception is raised and not caught the program terminates and
with diagnostic information that includes the name of the exception. This name
can be copied and written into the code so that the exception will be
caught in future. See also Arithmetic
You can raise your own exceptions using a THROW statement. In
C#, a throw takes an argument that is an expression (typically a
variable) that evaluates to a .NET exception class.
FTN95 recognises a similar syntax but for simplicity it
also allows you to use a CHARACTER string variable as an argument to
specify the name of the class directly.
Thus in FTN95 a THROW statement can take the form:
This string variable can also be used as the argument for the corresponding
CATCH statement. (When you use THROW with a character string
argument, FTN95 raises an exception using a class called
Salford.Fortran.UserException. This class has a member that is a string
variable whose value is the string that has been used as the argument
When using a CHARACTER string variable to THROW an exception it is still
possible handle multiple exceptions. To do this you simply re-throw
any exceptions that are not handled by the current CATCH. For example:
!Handle two particular exceptions and throw the rest to a
possible outer try block
IF(EXC /= 'MyException_1' .AND. EXC /= 'MyException_5')
These CHARACTER variables are standard Fortran strings so you should
ensure that they are long enough to avoid truncation.