In the following example, part of an application makes a series of subroutine calls:
CALL ROUTN1( A, B, STATUS ) CALL ROUTN2( C, STATUS ) CALL ROUTN3( T, Z, STATUS ) * Check the global status. IF ( STATUS .NE. SAI__OK ) GO TO 999 ... 999 CONTINUE END
Each of these subroutines uses the inherited status strategy and makes error reports by calling ERR_REP. If an error occurs within any of the subroutines, STATUS will be set to an error value by that routine and inherited status checking by all subsequent routines will cause them not to execute. Thus, it becomes unnecessary to check for an error after each subroutine call, and a single check at the end of a sequence of calls is all that is required to correctly handle any error condition that may arise. Because an error report will already have been made by the subroutine that failed, it is usually sufficient simply to abort if an error arises in a sequence of subroutine calls.
It is important to distinguish the case where a called subroutine sets STATUS and makes its own error report, as above, from the case where STATUS is set explicitly as a result of a directly detected error, as in the previous example. If the error reporting strategy is to function correctly, then responsibility for reporting the error must lie with the routine which modifies the status argument. The golden rule is therefore:
If STATUS is explicitly set to an error value, then an accompanying call to ERR_REP must be made.
Unless there are good documented reasons why this cannot be done, subroutines which return a status value and do not make an accompanying error report should be regarded as containing a bug1.
MERS (MSG and ERR) Message and Error Reporting Systems