Article
· 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.

Discussion (6)1
Log in or sign up to continue

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

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

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

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 )
  • error code 100 do not exist, but there is a code 101. See documentation: General Error Messages
    USER>s $mvv(58)="es"
     
    USER>d $SYSTEM.OBJ.DisplayError($System.Status.Error(101))
     
    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.

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.