ObjectScript error handling snippets
ObjectScript has at least three ways of handling errors (status codes, exceptions, SQLCODE, etc.). Most of the system code uses statuses but exceptions are easier to handle for a number of reasons. Working with legacy code you spend some time translating between the different techniques. I use these snippets a lot for reference. Hopefully they're useful to others as well.
///Status from SQLCODE: set st = $$$ERROR($$$SQLError, SQLCODE, $g(%msg)) //embedded SQL set st = $$$ERROR($$$SQLError, rs.%SQLCODE, $g(rs.%Message)) //dynamic SQL ///Exception from SQLCODE: throw ##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg) //embedded SQL throw ##class(%Exception.SQL).CreateFromSQLCODE(rs.%SQLCODE,rs.%Message) //dynamic SQL throw:(SQLCODE'=0)&&(SQLCODE'=100) ##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg) //don't throw if query succeeds or finds no data ///Exception from status: $$$ThrowOnError(st) ///Status from exception: set st = err.AsStatus() ///Creating a custom error status: set st = $$$ERROR($$$GeneralError,"Custom error message") ///Throwing a custom exception: $$$ThrowStatus($$$ERROR($$$GeneralError,"Custom error message")) ///Handling a SOAP error with a status: try { //SOAP request code } Catch err { If err.Name["ZSOAP" { Set st = %objlasterror } Else { Set st = err.AsStatus() } } return st ///Defining a custom exception class Class App.Exceptions.SomeException Extends %Exception.AbstractException { Method OnAsStatus() As %Status { return $$$ERROR($$$GeneralError,"Custom error message") } } ///Throwing and catching a custom exception try { throw ##class(App.Exceptions.SomeException).%New() } catch err { if err.%ClassName(1) = ##class(App.Exceptions.SomeException).%ClassName(1) { //some handling unique to this type of exception } }
Comments
Great article!
Here's a relevant article by @Vitaliy Serdtsev on localizing error messages.
Nice post, Pravin. In bookmarks!
This is one of my favorite posts - and my favorite code snippet that will log an error and return a status:
try {
}
catch (ex) {
do ex.Log()
set ok=ex.AsStatus()
}
quit ok
The article is considered as InterSystems Data Platform Best Practice.
I use a similar approach but in a routine file.
So, I just have an include at the top and then I do
$$$TryCatch
...
$$$TryEnd