Article
· Feb 7 6m read

IRIS %Status and Exceptions Part-2

In this article, exceptions are covered.

Working with Exceptions

Instead of returning a %Status response, you can raise and throw an Exception. You are then responsible for catching the exception and validating it. IRIS provides five main classes to handle exceptions effectively. Additionally, you can create custom exception class definition based on your needs.

These exceptions are different from %Status, so you can't directly/efficiently use the exception object with $SYSTEM.OBJ.DisplayError() or $SYSTEM.Status.DisplayError(). Instead, use the DisplayString() method to display the exception message Alternatively, you can convert the exception to %Status using the AsStatus() method and use the display methods mentioned above.

All exceptions inherit from %Exception.AbstractException. When you instantiate the object, use the %OnNew() callback method to set values since the formal parameters are common.

Set exception = ##Class(%Exception.General).%New(pName, pCode, pLocation, pData, pInnerException)

Where:

  • pName - is the Name is the name of the error(error message).
  • pCode - is the error code (like $$$GeneralError, $$$NamespaceDoesNotExist, or custom numbers when using a general exception).
  • pLocation - is the location where the error occurred.
  • pData - Data is extra information supplied for certain errors.
  • pInnerException - is an optional inner exception.

Let's continue with the 5 major exceptions

%Exception.SystemException

This exception is raised when a system process terminates with an error. IRIS raises this system error by default. Additionally, $ZERROR and $ECODE are defined when this exception is raised.

ClassMethod SystemException()
{
    Set $ECODE=""
    Set $ZREFERENCE=""
    Set $ZERROR=""
    Try {
        Write ^(1)
    }
    catch ex {
        Write $ECODE,!
        Write $ZERROR,!
        Write ex.DisplayString()
    }
}


Result

LEARNING>Do ##class(Learning.myexcept).SystemException()
,M1,
<NAKED>SystemException+5^Learning.myexcept.1
<NAKED> 30 SystemException+5^Learning.myexcept.1
LEARNING>

 

%Exception.StatusException

This Exception behaves similarly to the %Status type exception. You can raise it using various macros, such as 

  • $$$THROWONERROR(%sc,%expr) - execute the expression, set into %sc and throw exception
  • $$$ThrowOnError(%expr) -  execute the expression, set into %sc internally and throw exception
  • $$$TOE(%sc,%expr) - Invoke $$$THROWONERROR(%sc,%expr)
  • $$$ThrowStatus(%sc) - Directly throw the exception

Most commonly used method to raise this exception is "CreateFromStatus" which accepts the %Status as a argument and convert into StatusException

ClassMethod StatusException()
{
	Set sc1 = $$$ERROR($$$UserCTRLC) 
	#dim sc As %Exception.StatusException = ##class(%Exception.StatusException).CreateFromStatus(sc1)
	#; display the error message
	Write sc.DisplayString()
	
	#; convert to %Status again
	Set st = sc.AsStatus()
	Do $SYSTEM.Status.DisplayError(st)
}

Result 

LEARNING>Do ##class(Test.Exception).StatusException()
ERROR #834: Login aborted
ERROR #834: Login aborted

 

%Exception.SQL

This Exception handles SQL errors, using SQLCODE and %msg values. There are two methods to create this exception

Example:
either way you can raise an exception

  •  $$$ThrowSQLCODE(%sqlcode,%message)
  • ##class(%Exception.SQL).CreateFromSQLCODE(%sqlcode,%message)

CreateFromSQLCODE : The first parameter is the SQL code, and the second is the message.
 

ClassMethod SQLExceptionBySQLCODE()
{
    Set tSQLException = ##class(%Exception.SQL).CreateFromSQLCODE(-30,"SAMPLE.PERSON1 not found")
    Write tSQLException.DisplayString(),!
    Set st = tSQLException.AsStatus()
    Do $SYSTEM.Status.DisplayError(st)
}

Create object instance: Create an instance of the exception and then handle it.

ClassMethod GeneralException()
{
    Set ex1 = ##class(%Exception.General).%New(,5001)  ; just for inner exception
    Set exGen = ##class(%Exception.General).%New("RegistrationException",5852,,"Invalid MRN",ex1)
    Write exGen.DisplayString()
    Set sc = exGen.AsStatus()
    Do $SYSTEM.OBJ.DisplayError(sc)
}

%Exception.PythonException

This Exception provides Python error information. Here is the simplified sample.

ClassMethod pythonException()
{
    Try{
        Do ..pyTest()
    }
    Catch ex {
        Write $classname(ex)_"  "_ex.DisplayString()
    }
}
ClassMethod pyTest() [ Language = python ]
{
    print(1/0)
}

Result 

LEARNING>Do ##class(Learning.myexcept).pythonException()
%Exception.PythonException  <PYTHON EXCEPTION> 246 <class 'ZeroDivisionError'>: division by zero
 
ERROR #5002: ObjectScript error: <PYTHON EXCEPTION> *<class 'ZeroDivisionError'>: division by zero1

 

Last but not least

Custom Exception classes

For application-specific errors, it's crucial to handle exceptions precisely. Incorporate string localization on error messages. You can create custom Exception class.

For instance, you can create custom error messages with different translations based on the session's language.

^IRIS.Msg("MyApp")="en"
^IRIS.Msg("MyApp","en",62536)="InvalidMRN"
^IRIS.Msg("MyApp","ru",62536)="недействительный MRN"
 

Simplified custom Exception class sample

 
MyApp.Exception

 

 
MyApp.Errors.inc

Execution of the custom exception

This method demonstrates how to raise and display custom exceptions in different languages, including English and Russian

Include MyApp.Errors
Class MyApp.Utils Extends %RegisteredObject
{
    ClassMethod CustomExpcetionInEng()
    {
        Set tmyappException = ##class(MyApp.Exception).%New(,$$$InvalidMRN)
        wWritetmyappException.DisplayString()
    }

    ClassMethod CustomExpcetionInRussian()
    {
        Do ##class(%MessageDictionary).SetSessionLanguage("ru")
        Set tmyappException = ##class(MyApp.Exception).%New(,$$$InvalidMRN)
        write tmyappException.DisplayString()
    }
}

 Results 

LEARNING>d ##Class(MyApp.Utils).CustomExpcetionInEng()
InvalidMRN 62536
LEARNING>d ##Class(MyApp.Utils).CustomExpcetionInRussian()
недействительный MRN 62536
LEARNING>

Conclusion

In these ways you can handle the exceptions and %Status errors efficiently in your application code. Handling the errors effectively extremely helps in many ways!

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