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 } }