The MESSAGE procedure issues error and informational messages using the same mechanism employed by built-in IDL routines. By default, the message is issued as an error, the message is output, and IDL performs the required error-handling actions (which can be controlled via the CATCH, ON_ERROR, and ON_IOERROR procedures). As a side-effect of issuing the error, the system variable !ERROR_STATE is set and the text of the error message is placed in !ERROR_STATE.MSG. (If there is an operating system component to the error message, !ERROR_STATE.SYS_MSG is updated as well).
The MESSAGE procedure supports the following uses:
- To issue a simple error message containing user-specified text.
- To issue a specific error from a message block by name, with optional arguments. The NAME keyword is required in this case; if the error is not defined in the default IDL message block, the BLOCK keyword is also required. See DEFINE_MSGBLK and DEFINE_MSGBLK_FROM_FILE for examples of this usage.
- To reissue the most recent error encountered by IDL. If the CATCH procedure is used to trap errors, the REISSUE_LAST keyword to MESSAGE can be used within the CATCH block to pass the error up to its caller. See Example 2 below for an example.
Note: The first thing MESSAGE does is issue an error. If the procedure that calls MESSAGE also defines a CATCH block, execution transfers to the CATCH block as soon as the error is issued, and before any text defined to be output by MESSAGE is printed unless one of the CONTINUE or INFORMATIONAL keywords is set.
If the call to the MESSAGE procedure causes execution to halt, traceback information is displayed automatically.
For more information on MESSAGE, see Additional Examples.
As an example, assume the statement:
message, 'Unexpected value encountered.'
is executed in a procedure named CALC. If an error occurs, the following message would be printed:
% CALC: Unexpected value encountered.
and execution would halt.
To issue a simple error message:
To issue a named message from a message block:
To reissue the most recent error:
A string value specifying the text to be displayed in a simple error message.
Note: The Text argument is only used when MESSAGE is issuing a simple error message; that is, if neither the NAME keyword nor the REISSUE_LAST keyword is present. If none of the Text argument, the NAME keyword, or the REISSUE_LAST keyword are present, MESSAGE returns quietly.
When issuing a named error using the NAME (and possibly BLOCK) keyword, the Argi arguments are substituted into the error format string, as described in the documentation for DEFINE_MSGBLK and DEFINE_MSGBLK_FROM_FILE.
Set this keyword to a string containing the name of the IDL message block to use. This keyword is ignored unless the NAME keyword is also present to specify a message name.
By default, MESSAGE throws the IDL_M_USER_ERR message from the IDL_MBLK_CORE message block. If you wish to provide something other than the default error message, you can define your own message blocks and error messages. See the DEFINE_MSGBLK and DEFINE_MSGBLK_FROM_FILE procedures for details. You can use the HELP, /MESSAGES command to see the currently defined message blocks.
Set this keyword to return after issuing the error instead of taking the action specified by ON_ERROR. Use this option when it is desirable to report an error and then continue processing.
Set this keyword to indicate that the error occurred while performing I/O. The action specified by the ON_IOERROR procedure is executed instead of ON_ERROR.
Many messages include the name of the routine that called MESSAGE at the beginning of the message text. Use the LEVEL keyword to an integer value to specify that the name of a routine further up in the current call chain should be used instead. Specify the value of LEVEL as described in the following table:
The currently active routine.
The absolute index of the routine to indicate. A value of 1 specifies the main level ($MAIN$), 2 indicates the routine called by $MAIN$, and so forth.
Negative values indicate the relative index of the desired routine moving backwards from the current one. Hence, -1 indicates the caller of the current routine.
The LEVEL keyword can be used to hide error handling helper routines from user view. The following procedure will issue an error on behalf of its caller. The calling routine’s name will appear in the resulting message, and not that of the error routine:
pro THROW_ERROR, text
on_error, 2 ; Stop in caller
MESSAGE, LEVEL=-1, text
Set this keyword to a string containing the name of the message to throw. By default, MESSAGE throws the IDL_M_USER_ERR message from the IDL_MBLK_CORE message block. NAME is often used in conjunction with the BLOCK keyword to throw a non-default message from a non-default message block.
Set this keyword to suppress printing of the issuing routine’s name at the beginning of the error message.
Usually, the message includes the message prefix string (as specified by the MSG_PREFIX field of the !ERROR_STATE system variable) at the beginning. Set this keyword to omit the prefix.
Set this keyword to prevent the message from printing to the screen and cause the other actions to proceed quietly. The error system variables are updated as usual.
Set this keyword to reissue the last error issued by IDL. By using this keyword in conjunction with the CATCH procedure, your code can catch an error caused by called code, perform recovery actions, and issue the error normally. See the Examples below for a demonstration of this approach.
Note: If this keyword is specified, no plain arguments or other keywords may be specified.
This example demonstrates the use of the CATCH procedure and the REISSUE_LAST keyword to the MESSAGE procedure to control errors. In this example, we write a procedure named GET_TWO_POINTERS, which creates and returns two image variables of identical size via pointer heap variables. One possible problem with such an operation is that the system may not have enough memory to allocate both images. We want this operation to be all or nothing, so if we fail to get both variables we need to free the variable we did get before allowing our caller to see the error:
PRO GET_TWO_POINTERS, D1, D2, P1, P2
; [D1, D2] - Input dimensions
; P1, P2 - Variables to receive pointers to images
ON_ERROR, 2 ; When we reissue error, have
; control returned to caller.
nullPtr = PTR_NEW() ; Create a NULL pointer.
P1 = (P2 = nullPtr) ; Set both pointers to NULL.
CATCH, error ; Establish catch block.
CATCH, /CANCEL ; Cancel catch block so an error
; here will not cause looping.
PTR_FREE, P1, P2 ; If P1 or P2 are non-NULL, free
P1 = (P2 = nullPtr) ; them so caller sees NULL pointers.
MESSAGE, /REISSUE_LAST ; Reissue the error. The caller
; will get control.
; This line is never reached, because MESSAGE causes an
; implicit return to the calling routine.
; We now have both images and can safely return.
Deprecated the TRACEBACK keyword
Added REISSUE_LAST keyword