Written by

Senior Cloud Architect at InterSystems
Article Eduard Lebedyuk · Dec 7, 2019 1m read

About %objlasterror

%objlasterror is a useful reference to the last error.

Every time $$$ERROR is called, %objlasterror is set to a result of this call.

It's important in cases where you want to convert exception to status:

Try {
   //  quality code
} Catch ex {
   Set sc = $g(%objlasterror, $$$OK)
   Set sc = $$$ADDSC(sc, ex.AsStatus())
}

Because AsStatus calls $$$ERROR under the wraps, the order is important, first you need to get %objlasterror and  convert exception after that.

For Java gateway this method of handling exceptions also works:

If ((ex.Name="<ZJGTW>") && $d(%objlasterror)) {
    Set sc = %objlasterror
} Else {
    Set sc = ex.AsStatus()
}

Comments

Alexey Maslov · Dec 9, 2019

Just a quick note: when errors are processed consistently, e.g. each %Status have been returned is processed with $$$TOE or $$$ThrowOnError  or $$$ThrowStatus macro, this approach seems to be excessive, and `set sc=ex.AsStatus()` is just enough. E.g. 

ClassMethod GetDBProp(pDBname, ByRef pProp, pDivide = 1) As %Status{
  try {
   new $namespace set $namespace="%SYS"
   set sc=1/pDivide ;potential <DIVIDE>
   $$$TOE(sc, ##Class(Config.Databases).Get(pDBname,.pProp))
  catch ex {
   set sc=ex.AsStatus()
  }
  quit sc}

For me, unexpected %objlasterror is no more than a sign of inaccurate coding, when some %Status values are not processed.

0
Eduard Lebedyuk  Dec 9, 2019 to Alexey Maslov

Depends on a coding style.

I prefer not to use/propagate exceptions, but rather %Status.

0
Alexey Maslov  Dec 9, 2019 to Eduard Lebedyuk

It seems that try / catch paradigm encourages one to propagate exceptions. Otherwise it's easy to get a "style mix" that looks unpleasant, something like: 

   ...
   set sc=##Class(Config.Databases).Get(pDBname,.pProp)
   if 'sc goto gDBPropQ; more characters to type and less expressive
  
  catch ex {
   set sc=ex.AsStatus()
  }
gDBPropQ
  quit sc}

or 

  ...
  set sc=##Class(Config.Databases).Get(pDBname,.pProp)
  if 'sc return sc; many exit points from one method contradicts
                   ; with reasonable principles of modular coding
 catch ex {
   set sc=ex.AsStatus()
 }
 return sc}

All this stuff is just IMHO, just an attempt to be consistent. 

0
Michael Davidovich · Jan 25, 2023

If one were to write or save %objlasterror's output to a database, how would one interpret these characters:

0 ß!>

I find pretty consistently I get this as part of the output which I can work around but isn't helpful.

0
Michael Davidovich  Jan 25, 2023 to Michael Davidovich

I think the WYSIWYG kicked out some chars:​​​

0
Eduard Lebedyuk  Jan 26, 2023 to Michael Davidovich

%objlasterror is %Status which is a binary format. You can store it in a property of a %Status type and use ODBC mode for SQL queries, or use $system.Status.DisplayError(sc) to get/store the display value.

0
Michael Davidovich  Jan 26, 2023 to Eduard Lebedyuk

Please correct me if I'm wrong but I found $system.Status.GetErrorText(sc) was the appropriate method to use over DisplayError() as DisplayError simply writes to the console and would not save to the database or a variable.

0