You may encounter errors during any point of program execution, and there are several ways to raise and handle these exceptions. In this article, we'll explore how exceptions are handled efficiently in IRIS.
One of the most commonly used return types is %Status, which is used by methods to indicate success or failure. Let's begin by discussing %Status values.
Working with %Status
The %Status return type is used to represent errors or success. Many system methods return %Status when an error occurs. You can create a similar structure for your application errors, or convert to %Status, even when you raised exceptions in your code.
Let's start creating the errors
Macros
When we talked about errors the Macros are essential and easy to create Status values in the code. IRIS provides several macros to create and handle errors within your application code.
The most commonly used macro is $$$ERROR.
$$$ERROR
The $$$ERROR macro specifically designed to generate and return a %Library.%Status value. It is your responsibility to check the status before continuing execution in your program. This macro is tightly coupled with general system errors. Keep the following points in mind when using this macro:
- The first argument (error codes) refers to general error codes inside the %occErrors include file.
- If you're using predefined errors from that include file, you can use the macro directly, with or without additional arguments.
Note: Before proceeding $SYSTEM.OBJ.DisplayError(status) or $SYSTEM.Status.DisplayError(status) used to display the error(s) and supports string localization
Set sc = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
Do $SYSTEM.OBJ.DisplayError(sc)
output: ERROR #5015: Namespace 'TEST' does not exist1
ObjectScriptObjectScript
Set sc = $$$ERROR($$$UserCTRLC)
Do $SYSTEM.OBJ.DisplayError(sc)
ouput: ERROR #834: Login aborted1
ObjectScriptObjectScript
If you use any other error code not listed in %occErrors, an "Unknown status code" error will be returned. Always use the predefined errorcode $$$GeneralError == 5001 for general error messages.
Unknown status code sample
Set sc = $$$ERROR(95875,"TEST Error")
Do $SYSTEM.Status.DisplayError(sc)
output: ERROR #95875: Unknown status code: 95875 (TEST Error)
ObjectScriptObjectScript
Set sc = $$$ERROR($$$GeneralError,"TEST Error")
Do $SYSTEM.OBJ.DisplayError(sc)
output: ERROR #5001: TEST Error
ObjectScriptObjectScript
$$$ADDSC
The %Status doesn't necessarily hold only one error. Your program can validate multiple conditions and keep track of all errors in a single status, then use the $$$ADDSC macro. For example, the %ValidateObject() method can return multiple errors in a single response, which uses this functionality.
The $$$ADDSC macro appends one status to another, and the $SYSTEM.Status.AppendStatus method performs the same function.
$$$ADDSC(sc1,sc2) / $SYSTEM.Status.AppendStatus(s1,s2) - append sc2 to sc1 and return a new status code.
ClassMethod AppendErrors()
{
Set sc1 = $$$ERROR($$$UserCTRLC)
Set sc2 = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
Set sc = $$$ADDSC(sc1,sc2)
Do $SYSTEM.Status.DisplayError(sc)
Write !
Set sc = $$$ADDSC(sc1,sc2)
Do $SYSTEM.Status.DisplayError(sc)
}
output
LEARNING>do ##class(Learning.ErrorHandling).AppendErrors()
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist
ObjectScriptObjectScript
both results are same!
$$$GETERRORCODE
$$$GETERRORCODE(status) - Returns the error code value from the Status . This macro is belongs from the %occStatus.inc
Set status = $$$ERROR($$$UserCTRLC)
Write $$$GETERRORCODE(status),!
#;output: 834
Set status = $$$ERROR($$$GeneralError,"TEST Error")
Write $$$GETERRORCODE(status)
#;output: 5001
ObjectScriptObjectScript
$$$GETERRORMESSAGE
$$$GETERRORMESSAGE(sc,num) - This macro is returns the portion of the error based on the num in the %Status
Here is an example.
ClassMethod GetErrorMsgMacro()
{
Set status = $$$ERROR($$$GeneralError,"TEST Error",1,$$$ERROR($$$GeneralError,"TEST Error2"))
write $$$GETERRORMESSAGE(status),! ; It prints "TEST Error"
#;
Set st = $$$GETERRORMESSAGE(status,3) ; it get the "$$$ERROR($$$GeneralError,"TEST Error2")" in 3rd position based on the 2nd argument
write $$$GETERRORMESSAGE(st),! ; it prints TEST Error2
}
LEARNING>Do ##class(Learning.myexcept).GetErrorMsgMacro()
TEST Error
TEST Error2
ObjectScriptObjectScript
Validate Return Status
Now that you've created the error and returned it to your program, the next step is validating whether the return response is successful or erroneous.
The $$$ISERR macro checks whether the status represents an error. It returns 1 if the status indicates an error, otherwise it returns 0. There's another macro, $$$ISOK, which returns 1 when the status is successful.
Displaying Errors
If your program unexpectedly errors out (always expect the unexpected), you need to display the error message. The %SYSTEM.Status class is specifically designed for viewing or creating %Status values (if you prefer not to use macros) and we already seen the samples above.
Here are equivalent methods in %SYSTEM.Status that replace the macros:
Macro | Methods |
$$$ISERR | $SYSTEM.Status.IsError() |
$$$ISOK | $SYSTEM.Status.IsOK() |
$$$ADDSC | $SYSTEM.Status.AppendStatus() |
$$$ERROR | $SYSTEM.Status.Error() |
$$$OK | $SYSTEM.Status.OK() |
$$$GETERRORCODE |
The Exceptions will be continued in the next article.