MAGUERR ;WOIFO/SG - ERROR HANDLING UTILITIES ; 3/9/09 12:53pm
 ;;3.0;IMAGING;**93**;Dec 02, 2009;Build 163
 ;; Per VHA Directive 2004-038, this routine should not be modified.
 ;; +---------------------------------------------------------------+
 ;; | Property of the US Government.                                |
 ;; | No permission to copy or redistribute this software is given. |
 ;; | Use of unreleased versions of this software requires the user |
 ;; | to execute a written test agreement with the VistA Imaging    |
 ;; | Development Office of the Department of Veterans Affairs,     |
 ;; | telephone (301) 734-0100.                                     |
 ;; |                                                               |
 ;; | The Food and Drug Administration classifies this software as  |
 ;; | a medical device.  As such, it may not be changed in any way. |
 ;; | Modifications to this software may result in an adulterated   |
 ;; | medical device under 21CFR820, the use of which is considered |
 ;; | to be a violation of US Federal Statutes.                     |
 ;; +---------------------------------------------------------------+
 ;;
 ; * Error codes are negative numbers.
 ;
 ; * The corresponding error messages are stored in the DIALOG file
 ;   (#.84). Dialog numbers are calculated as follows:
 ;
 ;         Dialog# = 20050000 - (ErrorCode / 1000).
 ;
 ;   For example, dialog number for the error code -9 is 20050000.009.
 ;
 ; * A message itself is stored in the second "^"-piece of the dialog
 ;   text line. The first piece determines the problem type:
 ;
 ;     I - Information. No actions are required.
 ;
 ;     W - Warning. There was a problem but the code was/will be
 ;         able to ignore/recover and continue. User input errors
 ;         have this type as well.
 ;
 ;     E - Error. The code encountered a major problem and could
 ;         not continue. Data, code, or both should be fixed!
 ;
 ; TEMPORARY ERROR STORAGE
 ; =======================
 ;
 ; ^TMP("MAG-ERRROR-STORAGE",$J,
 ;   Seq#,
 ;     0)                Error Descriptor (see the $$ERROR^MAGUERR)
 ;                         ^01: Error code
 ;                         ^02: Error message
 ;                         ^03: Error location (TAG~ROUTINE)
 ;                         ^04: Type ("W" - warning, "E" - error)
 ;     1,Seq#)           Error details text (optional)
 ;
 ; Information messages (the "I" type) are never stored regardless
 ; of the mode set by the CLEAR^MAGUERR.
 ;
 Q
 ;
 ;##### INITIALIZES THE ERROR STORAGE
 ;
 ; [ENABLE]      Enable/disable error storage (0|1). If the storage
 ;               enabled, the $$ERROR function stores the error
 ;               descriptors there. Otherwise, only the latest
 ;               error descriptor is accessible (the result value
 ;               of the $$ERROR or $$DBS functions).
 ;
 ; This procedure also clears the error storage (regardless of the
 ; value of the ENABLE parameter).
 ;
CLEAR(ENABLE) ;
 S:'($D(ENABLE)#10) ENABLE=$D(^TMP("MAG-ERRROR-STORAGE",$J))#10
 K ^TMP("MAG-ERRROR-STORAGE",$J)
 S:ENABLE ^TMP("MAG-ERRROR-STORAGE",$J)=""
 D CLEAN^DILF
 Q
 ;
 ;##### CHECKS THE ERRORS AFTER A FILEMAN DBS CALL
 ;
 ; MAG8MSG       Closed reference of the error message array
 ;               (from a DBS call). If this parameter is empty,
 ;               then the ^TMP("DIERR",$J) is assumed.
 ;
 ; [FILE]        File number used in the DBS call.
 ; [IENS]        IENS used in the DBS call.
 ;
 ; This function checks the DIERR and @MAG8MSG variables after
 ; a FileMan DBS call and returns the error descriptor in case of
 ; error(s).
 ; 
 ; Return Values
 ; =============
 ;           <0  -9^Message text^Error location^Message type
 ;            0  No errors
 ;
 ; Notes
 ; =====
 ;
 ; If the error storage is enabled (see the CLEAR^MAGUERR), the
 ; messages returned by the FileMan call are recorded along with
 ; the error descriptor.  Otherwise, they are discarded.
 ; 
 ; This entry point can also be called as a procedure:
 ; D DBS^MAGUERR(...) if you do not need its return value.
 ;
DBS(MAG8MSG,FILE,IENS) ;
 I '$G(DIERR)  Q:$QUIT 0  Q
 N MSGTEXT,TMP
 ;--- Format the FileMan error messages
 D MSG^DIALOG("AE",.MSGTEXT,,,$G(MAG8MSG)),CLEAN^DILF
 ;--- Record the error message
 S TMP=$S($G(FILE):"; File #"_FILE,1:"")
 S:$G(IENS)'="" TMP=TMP_"; IENS: """_IENS_""""
 S TMP=$$ERROR(-9,.MSGTEXT,TMP)
 Q:$QUIT TMP  Q
 ;
 ;##### GENERATES THE ERROR MESSAGE
 ;
 ; ERRCODE       Error code (negative number).
 ;
 ;               If the error code has the 'S' suffix (e.g. "-3S"),
 ;               then the error info is NOT stored regardless of the
 ;               storage mode set by the CLEAR^MAGUERR.
 ;
 ; [[.]MAGINFO]  Optional additional information: either a string or
 ;               a reference to a local array that contains strings
 ;               prepared for storage in a word processing field
 ;               (first level nodes; no 0-nodes).
 ;
 ; [ARG1-ARG5]   Optional parameters for $$MSG^MAGUERR.
 ;
 ; Return Values
 ; =============
 ;           <0  Error code^Message text^Error location^Message type
 ;            0  Ok (if ERRCODE'<0)
 ;
 ; Notes
 ; =====
 ;
 ; "^" is replaced with "~" in the error location stored in the 3rd
 ; piece of the error descriptor.
 ;
 ; If error storage is enabled by the CLEAR^MAGUERR and type is other 
 ; than information (I), then this procedure saves the message info
 ; to the temporary error storage.
 ;
 ; This entry point can also be called as a procedure:
 ; D ERROR^MAGUERR(...) if you do not need its return value.
 ;
ERROR(ERRCODE,MAGINFO,ARG1,ARG2,ARG3,ARG4,ARG5) ;
 I ERRCODE'<0  Q:$QUIT 0  Q
 N MSG,PLACE,SL,TYPE
 ;--- Get the error location
 S SL=$STACK(-1)-1,PLACE=""
 F  Q:SL'>0  D  Q:'(PLACE[$T(+0))  S SL=SL-1
 . S PLACE=$P($STACK(SL,"PLACE")," ")
 . Q
 ;--- Prepare the additional information
 I $D(MAGINFO)=1  S MSG=MAGINFO  K MAGINFO  S MAGINFO(1)=MSG
 ;--- Prepare the message descriptor
 S MSG=$$MSG(+ERRCODE,.TYPE,.ARG1,.ARG2,.ARG3,.ARG4,.ARG5)
 S MSG=(+ERRCODE)_U_MSG_U_$TR(PLACE,U,"~")_U_TYPE
 ;--- Store the error info
 I TYPE'="I",ERRCODE'["S"  D STORE(MSG,.MAGINFO)
 ;---
 Q:$QUIT MSG  Q
 ;
 ;##### GENERATES THE 'INVALID PARAMETER VALUE' ERROR
 ;
 ; MAG8NAME      Closed reference to the variable/node
 ;
 ; [DSPNAME]     Display name of the parameter. If this parameter is
 ;               defined and not empty, its value is used as the
 ;               parameter name in the error message (instead of the
 ;               name passed in the MAG8NAME parameter).
 ;
 ; Return Values
 ; =============
 ;               -3^Message text^Error location^Message type
 ;
 ; Notes
 ; =====
 ;
 ; This entry point can also be called as a procedure:
 ; D IPVE^MAGUERR(...) if you do not need its return value.
 ;
IPVE(MAG8NAME,DSPNAME) ;
 N MAG8RC
 S MAG8RC=$S($D(@MAG8NAME)#2:"'"_@MAG8NAME_"'",1:"<UNDEFINED>")
 S MAG8RC=$$ERROR(-3,,$S($G(DSPNAME)'="":DSPNAME,1:MAG8NAME),MAG8RC)
 Q:$QUIT MAG8RC  Q
 ;
 ;##### RETURNS THE TEXT AND TYPE OF THE MESSAGE
 ;
 ; ERRCODE       Error code
 ;
 ; [.TYPE]       Reference to a local variable where the problem
 ;               type is returned ("I" -  Information, "W" - warning, 
 ;               "E" - error).
 ;
 ; [ARG1-ARG5]   Optional parameters that substitute the |n| "windows"
 ;               in the text of the message (for example, the |2| will
 ;               be substituted by the value of the ARG2).
 ;
 ; Return Values
 ; =============
 ;               Text of the error message
 ;
 ; Notes
 ; =====
 ;
 ; The "^" is replaced with the "~" in the message text.
 ;
MSG(ERRCODE,TYPE,ARG1,ARG2,ARG3,ARG4,ARG5) ;
 Q:ERRCODE'<0 ""
 N ARG,I1,I2,MSG
 ;--- Get a descriptor of the message
 S MSG=$$EZBLD^DIALOG(20050000-(ERRCODE/1000))
 ;--- Parse and validate the descriptor
 S TYPE=$E(MSG),MSG=$P(MSG,U,2,999)
 S:("IWE"'[TYPE)!(TYPE="") TYPE="E"
 Q:MSG?." " "Unknown error ("_ERRCODE_")"
 ;--- Substitute parameters
 S I1=2
 F  S I1=$F(MSG,"|",I1-1)  Q:'I1  D
 . S I2=$F(MSG,"|",I1)  Q:'I2
 . X "S ARG=$G(ARG"_+$TR($E(MSG,I1,I2-2)," ")_")"
 . S $E(MSG,I1-1,I2-1)=ARG
 . Q
 Q $TR($$TRIM^XLFSTR(MSG),U,"~")
 ;
 ;##### ASSIGNS THE DEFAULT ERROR HANDLER
 ;
 ; [RCVNAME]     Name of a variable for the error code
 ;
 ;               See the RTEHNDLR^MAGUERR1 for more details and the
 ;               SETPROPS^MAGGA02 for a usage example.
 ;
SETDEFEH(RCVNAME) ;
 S $ECODE=""
 S $ETRAP="D RTEHNDLR^MAGUERR1("_$$DDQ^MAGUTL05($G(RCVNAME))_")"
 Q
 ;
 ;##### STORES THE ERROR INFO
 ;
 ; ERROR         Error descriptor
 ;
 ; [.MAGINFO]    Reference to a local array with additional
 ;               information
 ;
STORE(ERROR,MAGINFO) ;
 Q:'$D(^TMP("MAG-ERRROR-STORAGE",$J))
 N IEN
 S IEN=$O(^TMP("MAG-ERRROR-STORAGE",$J," "),-1)+1
 S ^TMP("MAG-ERRROR-STORAGE",$J,IEN,0)=ERROR
 M ^TMP("MAG-ERRROR-STORAGE",$J,IEN,1)=MAGINFO
 Q
 
--- Routine Detail   --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HMAGUERR   9086     printed  Sep 23, 2025@19:45:11                                                                                                                                                                                                     Page 2
MAGUERR   ;WOIFO/SG - ERROR HANDLING UTILITIES ; 3/9/09 12:53pm
 +1       ;;3.0;IMAGING;**93**;Dec 02, 2009;Build 163
 +2       ;; Per VHA Directive 2004-038, this routine should not be modified.
 +3       ;; +---------------------------------------------------------------+
 +4       ;; | Property of the US Government.                                |
 +5       ;; | No permission to copy or redistribute this software is given. |
 +6       ;; | Use of unreleased versions of this software requires the user |
 +7       ;; | to execute a written test agreement with the VistA Imaging    |
 +8       ;; | Development Office of the Department of Veterans Affairs,     |
 +9       ;; | telephone (301) 734-0100.                                     |
 +10      ;; |                                                               |
 +11      ;; | The Food and Drug Administration classifies this software as  |
 +12      ;; | a medical device.  As such, it may not be changed in any way. |
 +13      ;; | Modifications to this software may result in an adulterated   |
 +14      ;; | medical device under 21CFR820, the use of which is considered |
 +15      ;; | to be a violation of US Federal Statutes.                     |
 +16      ;; +---------------------------------------------------------------+
 +17      ;;
 +18      ; * Error codes are negative numbers.
 +19      ;
 +20      ; * The corresponding error messages are stored in the DIALOG file
 +21      ;   (#.84). Dialog numbers are calculated as follows:
 +22      ;
 +23      ;         Dialog# = 20050000 - (ErrorCode / 1000).
 +24      ;
 +25      ;   For example, dialog number for the error code -9 is 20050000.009.
 +26      ;
 +27      ; * A message itself is stored in the second "^"-piece of the dialog
 +28      ;   text line. The first piece determines the problem type:
 +29      ;
 +30      ;     I - Information. No actions are required.
 +31      ;
 +32      ;     W - Warning. There was a problem but the code was/will be
 +33      ;         able to ignore/recover and continue. User input errors
 +34      ;         have this type as well.
 +35      ;
 +36      ;     E - Error. The code encountered a major problem and could
 +37      ;         not continue. Data, code, or both should be fixed!
 +38      ;
 +39      ; TEMPORARY ERROR STORAGE
 +40      ; =======================
 +41      ;
 +42      ; ^TMP("MAG-ERRROR-STORAGE",$J,
 +43      ;   Seq#,
 +44      ;     0)                Error Descriptor (see the $$ERROR^MAGUERR)
 +45      ;                         ^01: Error code
 +46      ;                         ^02: Error message
 +47      ;                         ^03: Error location (TAG~ROUTINE)
 +48      ;                         ^04: Type ("W" - warning, "E" - error)
 +49      ;     1,Seq#)           Error details text (optional)
 +50      ;
 +51      ; Information messages (the "I" type) are never stored regardless
 +52      ; of the mode set by the CLEAR^MAGUERR.
 +53      ;
 +54       QUIT 
 +55      ;
 +56      ;##### INITIALIZES THE ERROR STORAGE
 +57      ;
 +58      ; [ENABLE]      Enable/disable error storage (0|1). If the storage
 +59      ;               enabled, the $$ERROR function stores the error
 +60      ;               descriptors there. Otherwise, only the latest
 +61      ;               error descriptor is accessible (the result value
 +62      ;               of the $$ERROR or $$DBS functions).
 +63      ;
 +64      ; This procedure also clears the error storage (regardless of the
 +65      ; value of the ENABLE parameter).
 +66      ;
CLEAR(ENABLE) ;
 +1        if '($DATA(ENABLE)#10)
               SET ENABLE=$DATA(^TMP("MAG-ERRROR-STORAGE",$JOB))#10
 +2        KILL ^TMP("MAG-ERRROR-STORAGE",$JOB)
 +3        if ENABLE
               SET ^TMP("MAG-ERRROR-STORAGE",$JOB)=""
 +4        DO CLEAN^DILF
 +5        QUIT 
 +6       ;
 +7       ;##### CHECKS THE ERRORS AFTER A FILEMAN DBS CALL
 +8       ;
 +9       ; MAG8MSG       Closed reference of the error message array
 +10      ;               (from a DBS call). If this parameter is empty,
 +11      ;               then the ^TMP("DIERR",$J) is assumed.
 +12      ;
 +13      ; [FILE]        File number used in the DBS call.
 +14      ; [IENS]        IENS used in the DBS call.
 +15      ;
 +16      ; This function checks the DIERR and @MAG8MSG variables after
 +17      ; a FileMan DBS call and returns the error descriptor in case of
 +18      ; error(s).
 +19      ; 
 +20      ; Return Values
 +21      ; =============
 +22      ;           <0  -9^Message text^Error location^Message type
 +23      ;            0  No errors
 +24      ;
 +25      ; Notes
 +26      ; =====
 +27      ;
 +28      ; If the error storage is enabled (see the CLEAR^MAGUERR), the
 +29      ; messages returned by the FileMan call are recorded along with
 +30      ; the error descriptor.  Otherwise, they are discarded.
 +31      ; 
 +32      ; This entry point can also be called as a procedure:
 +33      ; D DBS^MAGUERR(...) if you do not need its return value.
 +34      ;
DBS(MAG8MSG,FILE,IENS) ;
 +1        IF '$GET(DIERR)
               if $QUIT
                   QUIT 0
               QUIT 
 +2        NEW MSGTEXT,TMP
 +3       ;--- Format the FileMan error messages
 +4        DO MSG^DIALOG("AE",.MSGTEXT,,,$GET(MAG8MSG))
           DO CLEAN^DILF
 +5       ;--- Record the error message
 +6        SET TMP=$SELECT($GET(FILE):"; File #"_FILE,1:"")
 +7        if $GET(IENS)'=""
               SET TMP=TMP_"; IENS: """_IENS_""""
 +8        SET TMP=$$ERROR(-9,.MSGTEXT,TMP)
 +9        if $QUIT
               QUIT TMP
           QUIT 
 +10      ;
 +11      ;##### GENERATES THE ERROR MESSAGE
 +12      ;
 +13      ; ERRCODE       Error code (negative number).
 +14      ;
 +15      ;               If the error code has the 'S' suffix (e.g. "-3S"),
 +16      ;               then the error info is NOT stored regardless of the
 +17      ;               storage mode set by the CLEAR^MAGUERR.
 +18      ;
 +19      ; [[.]MAGINFO]  Optional additional information: either a string or
 +20      ;               a reference to a local array that contains strings
 +21      ;               prepared for storage in a word processing field
 +22      ;               (first level nodes; no 0-nodes).
 +23      ;
 +24      ; [ARG1-ARG5]   Optional parameters for $$MSG^MAGUERR.
 +25      ;
 +26      ; Return Values
 +27      ; =============
 +28      ;           <0  Error code^Message text^Error location^Message type
 +29      ;            0  Ok (if ERRCODE'<0)
 +30      ;
 +31      ; Notes
 +32      ; =====
 +33      ;
 +34      ; "^" is replaced with "~" in the error location stored in the 3rd
 +35      ; piece of the error descriptor.
 +36      ;
 +37      ; If error storage is enabled by the CLEAR^MAGUERR and type is other 
 +38      ; than information (I), then this procedure saves the message info
 +39      ; to the temporary error storage.
 +40      ;
 +41      ; This entry point can also be called as a procedure:
 +42      ; D ERROR^MAGUERR(...) if you do not need its return value.
 +43      ;
ERROR(ERRCODE,MAGINFO,ARG1,ARG2,ARG3,ARG4,ARG5) ;
 +1        IF ERRCODE'<0
               if $QUIT
                   QUIT 0
               QUIT 
 +2        NEW MSG,PLACE,SL,TYPE
 +3       ;--- Get the error location
 +4        SET SL=$STACK(-1)-1
           SET PLACE=""
 +5        FOR 
               if SL'>0
                   QUIT 
               Begin DoDot:1
 +6                SET PLACE=$PIECE($STACK(SL,"PLACE")," ")
 +7                QUIT 
               End DoDot:1
               if '(PLACE[$TEXT(+0))
                   QUIT 
               SET SL=SL-1
 +8       ;--- Prepare the additional information
 +9        IF $DATA(MAGINFO)=1
               SET MSG=MAGINFO
               KILL MAGINFO
               SET MAGINFO(1)=MSG
 +10      ;--- Prepare the message descriptor
 +11       SET MSG=$$MSG(+ERRCODE,.TYPE,.ARG1,.ARG2,.ARG3,.ARG4,.ARG5)
 +12       SET MSG=(+ERRCODE)_U_MSG_U_$TRANSLATE(PLACE,U,"~")_U_TYPE
 +13      ;--- Store the error info
 +14       IF TYPE'="I"
               IF ERRCODE'["S"
                   DO STORE(MSG,.MAGINFO)
 +15      ;---
 +16       if $QUIT
               QUIT MSG
           QUIT 
 +17      ;
 +18      ;##### GENERATES THE 'INVALID PARAMETER VALUE' ERROR
 +19      ;
 +20      ; MAG8NAME      Closed reference to the variable/node
 +21      ;
 +22      ; [DSPNAME]     Display name of the parameter. If this parameter is
 +23      ;               defined and not empty, its value is used as the
 +24      ;               parameter name in the error message (instead of the
 +25      ;               name passed in the MAG8NAME parameter).
 +26      ;
 +27      ; Return Values
 +28      ; =============
 +29      ;               -3^Message text^Error location^Message type
 +30      ;
 +31      ; Notes
 +32      ; =====
 +33      ;
 +34      ; This entry point can also be called as a procedure:
 +35      ; D IPVE^MAGUERR(...) if you do not need its return value.
 +36      ;
IPVE(MAG8NAME,DSPNAME) ;
 +1        NEW MAG8RC
 +2        SET MAG8RC=$SELECT($DATA(@MAG8NAME)#2:"'"_@MAG8NAME_"'",1:"<UNDEFINED>")
 +3        SET MAG8RC=$$ERROR(-3,,$SELECT($GET(DSPNAME)'="":DSPNAME,1:MAG8NAME),MAG8RC)
 +4        if $QUIT
               QUIT MAG8RC
           QUIT 
 +5       ;
 +6       ;##### RETURNS THE TEXT AND TYPE OF THE MESSAGE
 +7       ;
 +8       ; ERRCODE       Error code
 +9       ;
 +10      ; [.TYPE]       Reference to a local variable where the problem
 +11      ;               type is returned ("I" -  Information, "W" - warning, 
 +12      ;               "E" - error).
 +13      ;
 +14      ; [ARG1-ARG5]   Optional parameters that substitute the |n| "windows"
 +15      ;               in the text of the message (for example, the |2| will
 +16      ;               be substituted by the value of the ARG2).
 +17      ;
 +18      ; Return Values
 +19      ; =============
 +20      ;               Text of the error message
 +21      ;
 +22      ; Notes
 +23      ; =====
 +24      ;
 +25      ; The "^" is replaced with the "~" in the message text.
 +26      ;
MSG(ERRCODE,TYPE,ARG1,ARG2,ARG3,ARG4,ARG5) ;
 +1        if ERRCODE'<0
               QUIT ""
 +2        NEW ARG,I1,I2,MSG
 +3       ;--- Get a descriptor of the message
 +4        SET MSG=$$EZBLD^DIALOG(20050000-(ERRCODE/1000))
 +5       ;--- Parse and validate the descriptor
 +6        SET TYPE=$EXTRACT(MSG)
           SET MSG=$PIECE(MSG,U,2,999)
 +7        if ("IWE"'[TYPE)!(TYPE="")
               SET TYPE="E"
 +8        if MSG?." "
               QUIT "Unknown error ("_ERRCODE_")"
 +9       ;--- Substitute parameters
 +10       SET I1=2
 +11       FOR 
               SET I1=$FIND(MSG,"|",I1-1)
               if 'I1
                   QUIT 
               Begin DoDot:1
 +12               SET I2=$FIND(MSG,"|",I1)
                   if 'I2
                       QUIT 
 +13               XECUTE "S ARG=$G(ARG"_+$TRANSLATE($EXTRACT(MSG,I1,I2-2)," ")_")"
 +14               SET $EXTRACT(MSG,I1-1,I2-1)=ARG
 +15               QUIT 
               End DoDot:1
 +16       QUIT $TRANSLATE($$TRIM^XLFSTR(MSG),U,"~")
 +17      ;
 +18      ;##### ASSIGNS THE DEFAULT ERROR HANDLER
 +19      ;
 +20      ; [RCVNAME]     Name of a variable for the error code
 +21      ;
 +22      ;               See the RTEHNDLR^MAGUERR1 for more details and the
 +23      ;               SETPROPS^MAGGA02 for a usage example.
 +24      ;
SETDEFEH(RCVNAME) ;
 +1        SET $ECODE=""
 +2        SET $ETRAP="D RTEHNDLR^MAGUERR1("_$$DDQ^MAGUTL05($GET(RCVNAME))_")"
 +3        QUIT 
 +4       ;
 +5       ;##### STORES THE ERROR INFO
 +6       ;
 +7       ; ERROR         Error descriptor
 +8       ;
 +9       ; [.MAGINFO]    Reference to a local array with additional
 +10      ;               information
 +11      ;
STORE(ERROR,MAGINFO) ;
 +1        if '$DATA(^TMP("MAG-ERRROR-STORAGE",$JOB))
               QUIT 
 +2        NEW IEN
 +3        SET IEN=$ORDER(^TMP("MAG-ERRROR-STORAGE",$JOB," "),-1)+1
 +4        SET ^TMP("MAG-ERRROR-STORAGE",$JOB,IEN,0)=ERROR
 +5        MERGE ^TMP("MAG-ERRROR-STORAGE",$JOB,IEN,1)=MAGINFO
 +6        QUIT