Written by

Architect at UnitedHealth Group (Optum)
Article Tirthankar Bachhar · Sep 27, 2016 3m read

Registering New Error Code and Error Message

How do we generally create an error object of %Status?

Set status=$SYSTEM.Status.Error($$$GeneralError,"Something went wrong")

Now, like $$$GeneralError there are many more macro defined within %occErrors include file by Intersystem which we can use.

i.e.
#define GeneralError                            5001
#define CacheError                               5002
#define NotImplemented                      5003
#define FeatureNotSupported               5014
#define DataMissing                             5022
#define FileCanNotCopy                       5024
#define FileAlreadyExists                      5027
#define DirectoryCannotCreate             5032
etc. and so on ...

Now, in many cases you might want to have a range of new errors and corresponding code defined for your product.

Example:

CODE1 - Invalid DOB for incoming patient.
CODE2 - Invalid Date for Date of Admission: <Date>
Etc..


What happen if we try to create error status object with code which is not register?
 

NSP>Set status=$SYSTEM.Status.Error("CODE1","Invalid DOB for incoming patient.")

NSP>Write $System.Status.GetErrorText(status)
ERROR #CODE1: Unknown status code: <UserErrors>CODE1 (Invalid DOB for incoming patient.)


Now, question is how do we get rid of the text - "Unknown status code"?
 

1. You can define a list of <Error>, <Error Code> and <Error Text> to be used within your code which is very specific to your client.

2. You need to create an XML as below to do so,

 <?xml version="1.0" encoding="UTF-8"?>
 <MsgFile Language="en">
  <MsgDomain Domain="UserErrors">
   <Message Id="-80001" Name="Problem">Something failed because of '%1'</Message>
   <Message Id="-1" Name="Other Problem">You Entered Invalid Data, Silly!</Message>
   <Message Id="-2" Name="Last Issue">You did %1 and it caused %2. Call %3.</Message>
  </MsgDomain>
 </MsgFile>

*** Recommended Notes from Intersystems Consultants (WRC/Kyle.Baxter):
 The Domain must be UserErrors, and the Message Id's must be negative integers. 
 After that, you are allowed to use %1, %2, %3 to customize the error message. 

3. How do we import the xml?

 Command to register:
 Write ##class(%MessageDictionary).Import("<Path to above XML>")
 
*** Note:
  Import from the %MessageDictionary only needs to be done once.
  Also, this xml can be maintained in svn, and shared accross clients/teams for reviewing.


Example Usage:

Case #1

NSP>Set status=$System.Status.Error(-2,"Something weird","Data Problems","Ghostbusters")
NSP>Do $SYSTEM.OBJ.DisplayError(status)

ERROR <UserErrors>-2: You did Something weird and it caused Data Problems. Call Ghostbusters.
 

Case #2

NSP>Set status=$System.Status.Error(-80001,"Mr X's Foolishness")
NSP>Do $SYSTEM.OBJ.DisplayError(status)

ERROR <UserErrors>-80001: Something failed because of 'Mr X's Foolishness'


*** Thanks to Kyle.Baxter for this solution.
*** Please add comments if you have any feedback, or issues for implementing the same.

Comments

PILAR GUERRERO · Jul 3, 2017

 

Does it let you put positive numbers in the XML file ?

0
Vitaliy Serdtsev  Jul 3, 2017 to PILAR GUERRERO

Yes, see part "Creation of a custom error message dictionary"

PS: you can even use the letters, for example:

<?xml <FONT COLOR="#008000">version</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"1.0" encoding</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"UTF-8"</FONT><FONT COLOR="#000000">?>
<</FONT><FONT COLOR="#000080">MsgFile </FONT><FONT COLOR="#800000">Language</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"en"</FONT><FONT COLOR="#000000">>
  <</FONT><FONT COLOR="#000080">MsgDomain </FONT><FONT COLOR="#800000">Domain</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"asd"</FONT><FONT COLOR="#000000">>
    <</FONT><FONT COLOR="#000080">Message </FONT><FONT COLOR="#800000">Id</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"a" </FONT><FONT COLOR="#800000">Name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"ErrorName1"</FONT><FONT COLOR="#000000">>Message about some error 1</</FONT><FONT COLOR="#000080">Message</FONT><FONT COLOR="#000000">>
    <</FONT><FONT COLOR="#000080">Message </FONT><FONT COLOR="#800000">Id</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"b" </FONT><FONT COLOR="#800000">Name</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"ErrorName2"</FONT><FONT COLOR="#000000">>Message about some error 2 %1 %2</</FONT><FONT COLOR="#000080">Message</FONT><FONT COLOR="#000000">>
  </</FONT><FONT COLOR="#000080">MsgDomain</FONT><FONT COLOR="#000000">>
</</FONT><FONT COLOR="#000080">MsgFile</FONT><FONT COLOR="#000000">></FONT>

0
PILAR GUERRERO · Jul 3, 2017

Hello,

i'm asking about positive number beacause when I try, for example:

<?xml version="1.0" encoding="UTF-8"?>
<MsgFile Language="en">
  <MsgDomain Domain="asd">
    <Message Id="100" Name="ErrorNumber">Message about some error number</Message>
    <Message Id="b" Name="ErrorName2">Message about some error 2 %1 %2</Message>
  </MsgDomain>
</MsgFile>

And then I use the terminal, but this doesn't work in the same way as letters or negative number..

>Write ##class(%MessageDictionary).Import("C:\--\CodigosError_20170628.xml")
1
>Set status=$System.Status.Error("100")                                    
>Do $SYSTEM.OBJ.DisplayError(status)                                       
ERROR #100: Código estado desconocido: 100 )
0
Rubens Silva  Jul 3, 2017 to PILAR GUERRERO

You can't use positive numbers because most of them are already defined inside %occErrors.inc and there's no way to inform which domain should the Error() use.

0
Vitaliy Serdtsev  Jul 3, 2017 to PILAR GUERRERO
  • error code 100 do not exist, but there is a code 101. See documentation: General Error Messages
    USER>s $mvv(58)="es"
    

    USER><FONT COLOR="#0000ff">d $SYSTEM</FONT><FONT COLOR="#008080">.OBJ</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">DisplayError</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$System</FONT><FONT COLOR="#008080">.Status</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Error</FONT><FONT COLOR="#000000">(101))</FONT>

    ERROR #101: Nivel puntero superior: nº bloques=%1 %2kb (%3% total)

  • error with some positive codes are reserved by the system, so you can't use them.
    Two error codes, 83 and 5001, are provided to enable you to generate your own custom error messages.
0
Rubens Silva  Jul 3, 2017 to Vitaliy Serdtsev

Yeah. I actually prefer using $$$GeneralError than creating my own error and having it display with <domain> before it's message. I think that" <domain>-errorcode: Message" pollutes the message for the end-user.
I did a test using the tutorial you posted (which is great by the way!), but the way the Status API display the error by default kind made me fallback to 5001, which is cleaner.

0