[85] | 1 | ;+ |
---|
| 2 | ; NAME: |
---|
| 3 | ; ERROR_MESSAGE |
---|
| 4 | ; |
---|
| 5 | ; PURPOSE: |
---|
| 6 | ; |
---|
| 7 | ; The purpose of this function is to have a device-independent |
---|
| 8 | ; error messaging function. The error message is reported |
---|
| 9 | ; to the user by using DIALOG_MESSAGE if widgets are |
---|
| 10 | ; supported and MESSAGE otherwise. |
---|
| 11 | ; |
---|
| 12 | ; In general, the ERROR_MESSAGE function is not called directly. |
---|
| 13 | ; Rather, it is used in a CATCH error handler. Errors are thrown |
---|
| 14 | ; to ERROR_MESSAGE with the MESSAGE command. A typical CATCH error |
---|
| 15 | ; handler is shown below. |
---|
| 16 | ; |
---|
| 17 | ; Catch, theError |
---|
| 18 | ; IF theError NE 0 THEN BEGIN |
---|
| 19 | ; Catch, /Cancel |
---|
| 20 | ; ok = Error_Message() |
---|
| 21 | ; RETURN |
---|
| 22 | ; ENDIF |
---|
| 23 | ; |
---|
| 24 | ; Error messages would get into the ERROR_MESSAGE function by |
---|
| 25 | ; throwing an error with the MESSAGE command, like this: |
---|
| 26 | ; |
---|
| 27 | ; IF test NE 1 THEN Message, 'The test failed.' |
---|
| 28 | ; |
---|
| 29 | ; AUTHOR: |
---|
| 30 | ; |
---|
| 31 | ; FANNING SOFTWARE CONSULTING |
---|
| 32 | ; David Fanning, Ph.D. |
---|
| 33 | ; 1645 Sheely Drive |
---|
| 34 | ; Fort Collins, CO 80526 USA |
---|
| 35 | ; Phone: 970-221-0438 |
---|
| 36 | ; E-mail: davidf@dfanning.com |
---|
| 37 | ; Coyote's Guide to IDL Programming: http://www.dfanning.com/ |
---|
| 38 | ; |
---|
| 39 | ; CATEGORY: |
---|
| 40 | ; |
---|
| 41 | ; Utility. |
---|
| 42 | ; |
---|
| 43 | ; CALLING SEQUENCE: |
---|
| 44 | ; |
---|
| 45 | ; ok = Error_Message(the_Error_Message) |
---|
| 46 | ; |
---|
| 47 | ; INPUTS: |
---|
| 48 | ; |
---|
| 49 | ; the_Error_Message: This is a string argument containing the error |
---|
| 50 | ; message you want reported. If undefined, this variable is set |
---|
| 51 | ; to the string in the !Error_State.Msg system variable. |
---|
| 52 | ; |
---|
| 53 | ; KEYWORDS: |
---|
| 54 | ; |
---|
| 55 | ; ERROR: Set this keyword to cause Dialog_Message to use the ERROR |
---|
| 56 | ; reporting dialog. Note that a bug in IDL causes the ERROR dialog |
---|
| 57 | ; to be used whether this keyword is set to 0 or 1! |
---|
| 58 | ; |
---|
| 59 | ; INFORMATIONAL: Set this keyword to cause Dialog_Message to use the |
---|
| 60 | ; INFORMATION dialog instead of the WARNING dialog. Note that a bug |
---|
| 61 | ; in IDL causes the ERROR dialog to be used if this keyword is set to 0! |
---|
| 62 | ; |
---|
| 63 | ; TITLE: Set this keyword to the title of the DIALOG_MESSAGE window. By |
---|
| 64 | ; default the keyword is set to 'System Error' unless !ERROR_STATE.NAME |
---|
| 65 | ; equals "IDL_M_USER_ERR", in which case it is set to "Trapped Error'. |
---|
| 66 | ; |
---|
| 67 | ; TRACEBACK: Setting this keyword results in an error traceback |
---|
| 68 | ; being printed to standard output with the PRINT command. Set to |
---|
| 69 | ; 1 (ON) by default. Use TRACEBACK=0 to turn this functionality off. |
---|
| 70 | ; |
---|
| 71 | ; OUTPUTS: |
---|
| 72 | ; |
---|
| 73 | ; Currently the only output from the function is the string "OK". |
---|
| 74 | ; |
---|
| 75 | ; RESTRICTIONS: |
---|
| 76 | ; |
---|
| 77 | ; The WARNING Dialog_Message dialog is used by default. |
---|
| 78 | ; |
---|
| 79 | ; EXAMPLE: |
---|
| 80 | ; |
---|
| 81 | ; To handle an undefined variable error: |
---|
| 82 | ; |
---|
| 83 | ; IF N_Elements(variable) EQ 0 THEN $ |
---|
| 84 | ; ok = Error_Message('Variable is undefined') |
---|
| 85 | ; |
---|
| 86 | ; MODIFICATION HISTORY: |
---|
| 87 | ; |
---|
| 88 | ; Written by: David W. Fanning, 27 April 1999. |
---|
| 89 | ; Added the calling routine's name in the message and NoName keyword. 31 Jan 2000. DWF. |
---|
| 90 | ; Added _Extra keyword. 10 February 2000. DWF. |
---|
| 91 | ; Forgot to add _Extra everywhere. Fixed for MAIN errors. 8 AUG 2000. DWF. |
---|
| 92 | ; Adding call routine's name to Traceback Report. 8 AUG 2000. DWF. |
---|
| 93 | ; Added ERROR, INFORMATIONAL, and TITLE keywords. 19 SEP 2002. DWF. |
---|
| 94 | ; Removed the requirement that you use the NONAME keyword with the MESSAGE |
---|
| 95 | ; command when generating user-trapped errors. 19 SEP 2002. DWF. |
---|
| 96 | ; Added distinctions between trapped errors (errors generated with the |
---|
| 97 | ; MESSAGE command) and IDL system errors. Note that if you call ERROR_MESSAGE |
---|
| 98 | ; directly, then the state of the !ERROR_STATE.NAME variable is set |
---|
| 99 | ; to the *last* error generated. It is better to access ERROR_MESSAGE |
---|
| 100 | ; indirectly in a Catch error handler from the MESSAGE command. 19 SEP 2002. DWF. |
---|
| 101 | ; Change on 19 SEP 2002 to eliminate NONAME requirement did not apply to object methods. |
---|
| 102 | ; Fixed program to also handle messages from object methods. 30 JULY 2003. DWF. |
---|
| 103 | ; Removed obsolete STR_SEP and replaced with STRSPLIT. 27 Oct 2004. DWF. |
---|
| 104 | ; Made a traceback the default case without setting TRACEBACK keyword. 19 Nov 2004. DWF. |
---|
| 105 | ; Added check for window connection specifically for CRON jobs. 6 May 2008. DWF. |
---|
| 106 | ;- |
---|
| 107 | ;########################################################################### |
---|
| 108 | ; |
---|
| 109 | ; LICENSE |
---|
| 110 | ; |
---|
| 111 | ; This software is OSI Certified Open Source Software. |
---|
| 112 | ; OSI Certified is a certification mark of the Open Source Initiative. |
---|
| 113 | ; |
---|
| 114 | ; Copyright 1999-2008 Fanning Software Consulting |
---|
| 115 | ; |
---|
| 116 | ; This software is provided "as-is", without any express or |
---|
| 117 | ; implied warranty. In no event will the authors be held liable |
---|
| 118 | ; for any damages arising from the use of this software. |
---|
| 119 | ; |
---|
| 120 | ; Permission is granted to anyone to use this software for any |
---|
| 121 | ; purpose, including commercial applications, and to alter it and |
---|
| 122 | ; redistribute it freely, subject to the following restrictions: |
---|
| 123 | ; |
---|
| 124 | ; 1. The origin of this software must not be misrepresented; you must |
---|
| 125 | ; not claim you wrote the original software. If you use this software |
---|
| 126 | ; in a product, an acknowledgment in the product documentation |
---|
| 127 | ; would be appreciated, but is not required. |
---|
| 128 | ; |
---|
| 129 | ; 2. Altered source versions must be plainly marked as such, and must |
---|
| 130 | ; not be misrepresented as being the original software. |
---|
| 131 | ; |
---|
| 132 | ; 3. This notice may not be removed or altered from any source distribution. |
---|
| 133 | ; |
---|
| 134 | ; For more information on Open Source Software, visit the Open Source |
---|
| 135 | ; web site: http://www.opensource.org. |
---|
| 136 | ; |
---|
| 137 | ;########################################################################### |
---|
| 138 | |
---|
| 139 | |
---|
| 140 | FUNCTION ERROR_MESSAGE, theMessage, Error=error, Informational=information, $ |
---|
| 141 | Traceback=traceback, NoName=noname, Title=title, _Extra=extra |
---|
| 142 | |
---|
| 143 | On_Error, 2 |
---|
| 144 | |
---|
| 145 | ; Check for presence and type of message. |
---|
| 146 | |
---|
| 147 | IF N_Elements(theMessage) EQ 0 THEN theMessage = !Error_State.Msg |
---|
| 148 | s = Size(theMessage) |
---|
| 149 | messageType = s[s[0]+1] |
---|
| 150 | IF messageType NE 7 THEN BEGIN |
---|
| 151 | Message, "The message parameter must be a string.", _Extra=extra |
---|
| 152 | ENDIF |
---|
| 153 | IF N_Elements(traceback) EQ 0 THEN traceback = 1 |
---|
| 154 | |
---|
| 155 | ; Get the call stack and the calling routine's name. |
---|
| 156 | Help, Calls=callStack |
---|
| 157 | callingRoutine = (StrSplit(StrCompress(callStack[1])," ", /Extract))[0] |
---|
| 158 | |
---|
| 159 | |
---|
| 160 | |
---|
| 161 | |
---|
| 162 | ; Are widgets supported? |
---|
| 163 | widgetsSupported = ((!D.Flags AND 65536L) NE 0) |
---|
| 164 | |
---|
| 165 | ; It is not enough to know if widgets are supported. In CRON jobs, widgets are |
---|
| 166 | ; supported, but there is no X connection and pop-up dialogs are not allowed. |
---|
| 167 | ; Here is a quick test to see if we can connect to a windowing system. If not, |
---|
| 168 | ; then we are going to assume widgets are not supported. |
---|
| 169 | Catch, theError |
---|
| 170 | IF theError NE 0 THEN BEGIN |
---|
| 171 | Catch, /CANCEL |
---|
| 172 | widgetsSupported = 0 |
---|
| 173 | GOTO, testWidgetSupport |
---|
| 174 | ENDIF |
---|
| 175 | theWindow = !D.Window |
---|
| 176 | Window, /FREE, XSIZE=5, YSIZE=5, /PIXMAP |
---|
| 177 | Catch, /CANCEL |
---|
| 178 | |
---|
| 179 | testWidgetSupport: ; Come here if you choke on creating a window. |
---|
| 180 | IF !D.Window NE theWindow THEN BEGIN |
---|
| 181 | WDelete, !D.Window |
---|
| 182 | IF theWindow GE 0 THEN WSet, theWindow |
---|
| 183 | ENDIF |
---|
| 184 | |
---|
| 185 | IF widgetsSupported THEN BEGIN |
---|
| 186 | |
---|
| 187 | ; If this is an error produced with the MESSAGE command, it is a trapped |
---|
| 188 | ; error and will have the name "IDL_M_USER_ERR". |
---|
| 189 | IF !ERROR_STATE.NAME EQ "IDL_M_USER_ERR" THEN BEGIN |
---|
| 190 | |
---|
| 191 | IF N_Elements(title) EQ 0 THEN title = 'Trapped Error' |
---|
| 192 | |
---|
| 193 | ; If the message has the name of the calling routine in it, |
---|
| 194 | ; it should be stripped out. Can you find a colon in the string? |
---|
| 195 | |
---|
| 196 | ; Is the calling routine an object method? If so, special processing |
---|
| 197 | ; is required. Object methods will have two colons together. |
---|
| 198 | doublecolon = StrPos(theMessage, "::") |
---|
| 199 | IF doublecolon NE -1 THEN BEGIN |
---|
| 200 | |
---|
| 201 | prefix = StrMid(theMessage, 0, doublecolon+2) |
---|
| 202 | submessage = StrMid(theMessage, doublecolon+2) |
---|
| 203 | colon = StrPos(submessage, ":") |
---|
| 204 | IF colon NE -1 THEN BEGIN |
---|
| 205 | |
---|
| 206 | ; Extract the text up to the colon. Is this the same as |
---|
| 207 | ; the callingRoutine? If so, strip it. |
---|
| 208 | IF StrMid(theMessage, 0, colon+StrLen(prefix)) EQ callingRoutine THEN $ |
---|
| 209 | theMessage = StrMid(theMessage, colon+1+StrLen(prefix)) |
---|
| 210 | ENDIF |
---|
| 211 | ENDIF ELSE BEGIN |
---|
| 212 | |
---|
| 213 | colon = StrPos(theMessage, ":") |
---|
| 214 | IF colon NE -1 THEN BEGIN |
---|
| 215 | |
---|
| 216 | ; Extract the text up to the colon. Is this the same as |
---|
| 217 | ; the callingRoutine? If so, strip it. |
---|
| 218 | IF StrMid(theMessage, 0, colon) EQ callingRoutine THEN $ |
---|
| 219 | theMessage = StrMid(theMessage, colon+1) |
---|
| 220 | ENDIF |
---|
| 221 | |
---|
| 222 | ENDELSE |
---|
| 223 | |
---|
| 224 | |
---|
| 225 | ; Add the calling routine's name, unless NONAME is set. |
---|
| 226 | IF Keyword_Set(noname) THEN BEGIN |
---|
| 227 | answer = Dialog_Message(theMessage, Title=title, _Extra=extra, $ |
---|
| 228 | Error=error, Information=information) |
---|
| 229 | ENDIF ELSE BEGIN |
---|
| 230 | answer = Dialog_Message(StrUpCase(callingRoutine) + ": " + $ |
---|
| 231 | theMessage, Title=title, _Extra=extra, $ |
---|
| 232 | Error=error, Information=information) |
---|
| 233 | ENDELSE |
---|
| 234 | |
---|
| 235 | ENDIF ELSE BEGIN |
---|
| 236 | |
---|
| 237 | ; Otherwise, this is an IDL system error. |
---|
| 238 | IF N_Elements(title) EQ 0 THEN title = 'System Error' |
---|
| 239 | |
---|
| 240 | IF StrUpCase(callingRoutine) EQ "$MAIN$" THEN $ |
---|
| 241 | answer = Dialog_Message(theMessage, _Extra=extra, Title=title, $ |
---|
| 242 | Error=error, Information=information) ELSE $ |
---|
| 243 | IF Keyword_Set(noname) THEN BEGIN |
---|
| 244 | answer = Dialog_Message(theMessage, _Extra=extra, Title=title, $ |
---|
| 245 | Error=error, Information=information) |
---|
| 246 | ENDIF ELSE BEGIN |
---|
| 247 | answer = Dialog_Message(StrUpCase(callingRoutine) + "--> " + $ |
---|
| 248 | theMessage, _Extra=extra, Title=title, $ |
---|
| 249 | Error=error, Information=information) |
---|
| 250 | ENDELSE |
---|
| 251 | ENDELSE |
---|
| 252 | ENDIF ELSE BEGIN |
---|
| 253 | Message, theMessage, /Continue, /NoPrint, /NoName, /NoPrefix, _Extra=extra |
---|
| 254 | Print, '%' + callingRoutine + ': ' + theMessage |
---|
| 255 | answer = 'OK' |
---|
| 256 | ENDELSE |
---|
| 257 | |
---|
| 258 | ; Provide traceback information if requested and this is NOT an informational message. |
---|
| 259 | IF Keyword_Set(traceback) AND ~Keyword_Set(informational)THEN BEGIN |
---|
| 260 | Help, /Last_Message, Output=traceback |
---|
| 261 | Print,'' |
---|
| 262 | Print, 'Traceback Report from ' + StrUpCase(callingRoutine) + ':' |
---|
| 263 | Print, '' |
---|
| 264 | FOR j=0,N_Elements(traceback)-1 DO Print, " " + traceback[j] |
---|
| 265 | ENDIF |
---|
| 266 | |
---|
| 267 | RETURN, answer |
---|
| 268 | END ; ---------------------------------------------------------------------------- |
---|
| 269 | |
---|