next up previous 211
Next: Reporting Status, Fortran I/O and operating system errors
Up: ERR - Error Reporting System
Previous: Intercepting error messages


Protecting tokens

As a general rule, message tokens should be assigned, using calls to the MSG_SETx and MSG_FMTx routines, immediately prior to the call in which they are to be used. However, this is not always convenient; e.g. within an iteration or a block IF statement where the same tokens may be used in one of several potential message reports. Under these circumstances, it is important to protect the values of assigned message tokens when subroutines which may fail are called - when a subroutine fails it must be assumed that it will make an accompanying error report using ERR_REP within the existing error reporting context, thereby annulling any currently defined message tokens. The only sure way of protecting against such behaviour is to bracket the subroutine call which may fail with calls to ERR_MARK and ERR_RLSE. The same precautions are needed when any subroutine is called which may in turn call any of MSG_OUT, MSG_OUTIF, MSG_LOAD, ERR_REP or ERR_LOAD (all of which annul tokens).

It is not good practice to assign message tokens which are to be used in another subroutine.

Here is an example of assigning message tokens outside a block IF statement to be used by ERR_REP and MSG_OUT calls within the IF block. The code is a fragment of a routine for re-scaling a single array to a mean of unity. If the call to the subroutine MEAN fails, any assigned message tokens in the current error reporting context may be annulled; hence the need to bracket this call by calls to ERR_MARK and ERR_RLSE.

*  Get the data arrays.
      CALL GETDAT( X, Y, QUAL, NDATA, STATUS )

*  Check the returned status.
      IF ( STATUS .EQ. SAI__OK ) THEN

*     The data have been obtained successfully, assign the token value 
*     and inform the user of the number of data obtained.
         CALL MSG_SETI( 'NDATA', NDATA )

         IF ( NDATA .LE. 0 ) THEN

*        No data exist, report an error message and abort.
            STATUS = SAI__ERROR
            CALL ERR_REP( 'NDATA_INVAL', 
     :                    'Cannot use this number of data (^NDATA).',
     :                    STATUS )
         ELSE

*        Get the mean of the data.
            CALL ERR_MARK
            CALL MEAN( NDATA, Y, QUAL, MEAN, STATUS )
            CALL ERR_RLSE

*        Check the returned status.
            IF ( STATUS .EQ. SAI__OK ) THEN

*           Deliver the number of data and their mean to the user.
               CALL MSG_SETR( 'MEAN', MEAN )

               IF ( NDATA .EQ. 1 ) THEN
                  CALL MSG_OUT( ' ', 
     :               '^NDATA data value (^MEAN) will be used.', 
     :               STATUS )
               ELSE
                  CALL MSG_OUT( ' ', 
     :               '^NDATA data values with a mean of ^MEAN' //
     :               ' will be used.', STATUS )
               END IF
            ELSE

*           Failed to calculate a mean value for the data (the quality
*           flags were probably all bad). Report an error and abort.
               IF ( NDATA .EQ. 1 ) THEN
                  CALL MSG_SETC( 'VALUE', 'value' )
               ELSE
                  CALL MSG_SETC( 'VALUE', 'values' )
               END IF

               CALL ERR_REP( 'BAD_DATA', 
     :            'No mean available for ^NDATA ^VALUE,', //
     :            ' cannot rescale the data.', STATUS )
            END IF
         END IF
      END IF



next up previous 211
Next: Reporting Status, Fortran I/O and operating system errors
Up: ERR - Error Reporting System
Previous: Intercepting error messages

MERS (MSG and ERR) Message and Error Reporting Systems
Starlink User Note 104
P C T Rees
A J Chipperfield
22 October 2001
E-mail:ussc@star.rl.ac.uk

Copyright © 2001 Council for the Central Laboratory of the Research Councils