Catching Exceptions

You can include multiple catch blocks within a calling subroutine to conditionally segregate exception handling based on exception codes. A catch statement marks the starting code location from which the compiler processes exceptions by the catch block. The compiler code evaluates catch blocks sequentially from top to bottom from the point of the call within a subroutine until the compiler encounters an exception filter containing the exception type. An exception filter can test for a single exception type or a comma-separated list of exception types. Conversely, a catch block without an exception filter processes all exception types.

Refer to the Error Class for a detailed description of  the properties and statements used in Exception Handling.

image\warning.gif

Use the catch statement and catch block structure instead of the GT.M exception handlers "set $zt…". This approach simplifies the readability of the code and integrates GT.M and application exception handling. Internally, PSL uses the GT.M exception handling infrastructure to implement branching, logging, and stack management for exceptions.

The syntax to catch an exception is:

catch Error {

            }

Example #1

The following example demonstrates catching GT.M exceptions and logging the exceptions to the Profile Error Report (SCAER).

catch Error {

      set ET=Error.type

      if ET[“%GTM-“ do ZE^UTLERR quit

      set ET=ET_”-“_Error.thrownAt

      set RM=Error.description

      do ^UTLERR

      }

Example #2

The following example demonstrates catching a GT.M exception and logging the exception to the Dayend Exception Report, SCA006:

catch Error {

      set ET=Error.type

      set ETLOC=Error.thrownAt

      set RM=Error.description

 

      do LOG^UTLEXC(“ZBCHLETEFT”, ... ”*”,””$G(CID)_”,”_$G(SEQ),ETLOC,ET)

      if ET[“%GTM-“ do ZE^UTLERR quit

      do ^UTLERR

      }

The compiler code sequentially evaluates catch blocks that appear in the calling block after the method or procedure, until it encounters a catch block containing the exception filter with the thrown exception type or it encounters a catch block without an exception filter. When the compiler encounters the catch block with the thrown exception type, it processes the catch block and deletes the exception object.

The scope of a catch block is the current stack level and descending stack levels, unless another catch statement is encountered. If multiple catch statements exist at the same stack level, the second statement overlays the first statement at the location of the second statement. If multiple catch statements exist at different stack levels, the second statement overlays the first statement at the location and stack level of the second statement. When the stack level is decremented (e.g., Quit), the scope of the first block is restored.

If the compiler does not catch an exception within a block, it passes the exception up the stack until it is caught or the program exits. When a stack level receives a thrown exception, the compiler code exits at the location of the method or procedure call after the appropriate catch block processes. The compiler code "cleans up" any objects that were instantiated within the scope of the calling block as if the compiler exited the block normally.

Catch blocks are normal PSL code blocks and can throw exceptions or receive exceptions from called methods and procedures like any other code block.

image\msgs.gif

If an error is thrown from inside a catch block, the compiler passes it to the catch block in effect at the previous stack error (to prevent infinite loops).