Fanning Software Consulting

Error Tracing in IDL Widget Programs

QUESTION: I'm using Catch routines to keep my widget program's event handlers running, as you suggest, but by doing so I can't figure out where the errors occur. Is there some way to get an error traceback in a widget program that is using a Catch error handler?

ANSWER: The problem with Catch error handlers in widget programs is that they keep your widget programs running forever. Most of us are used to programs that break. In fact, if our programs don't break, we have trouble fixing them (see any treatise on object graphics for an example).

It would be helpful to at least know what line your program was complaining about. But if you put a simple "Help, /Traceback" in the Catch error handler, you learn that you are in your error handler. Well, duh! I guess so.

What you really want to know about is what problem occurred just before you got into your error handler, and print a traceback to that problem. This can be accomplished, but it is a little more difficult.

The first thing you really what to know is what event handler is it that is producing the error. You can get this information from the Help command and the calling stack, like this:

   Help, Calls=callStack
   callingRoutine = (Str_Sep(StrCompress(callStack[1])," "))[0]

Then you want to print out the last message that really caused the error by using the Last_Message keyword to the Help command. The code might look something like this:

   Help, /Last_Message, Output=traceback
   Print,''
   Print, 'Traceback Report from ' + StrUpCase(callingRoutine) + ':'
   Print, ''
   FOR j=0,N_Elements(traceback)-1 DO Print, "     " + traceback[j]

All of this code has been incorporated into the program cgErrorMsg so I can have a sort of one-stop-fits-all type of Catch error handler. Most of the error handlers in my widget program event handlers look more or less like this:

   Catch, theError
   IF theError NE 0 THEN BEGIN
      Catch, /Cancel
      void = cgErrorMsg()
      RETURN
    ENDIF

Used this way, the cgErrorMsg error handler uses Dialog_Message to post the error message set in !Error_State.MSG, and it prints traceback information to the Command Log (or standard output) window. Here is an example of an error message and it's subsequent traceback.

The message from cgErrorMsg.

Traceback Report from FSC_SURFACE_ELEVATION_COLORS:

     % Case statement found no matches.
     % Execution halted at:  FSC_SURFACE_ELEVATION_COLORS  388 C:\IDL\IDL54\david\fsc_surface.pro
     %                       $MAIN$                 

I can print my own messages to cgErrorMsg by throwing errors like this:

   IF test EQ 0 THEN Message, 'The test failed, my Man.', /NoName

The user-written message from cgErrorMsg.

Google
 
Web Coyote's Guide to IDL Programming