65.9K
CodeProject is changing. Read more.
Home

Exception Handling In Micro Focus Managed COBOL

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0 vote)

May 19, 2010

CC (ASA 2.5)

2 min read

viewsIcon

12760

Exception Handling In Micro Focus Managed COBOL

Sometimes things don't work out the way we expect!

Micro Focus Managed COBOL has a powerful and flexible exception handling system evolved from similar systems in Java, VB and C#. Here is a quick introduction.

The 2002 standard for COBOL did introduce an exception handling mechanism. However, this mechanism has not proved to be very popular amongst COBOL programmers. The direction of Managed COBOL has been to take advantage of the lessons learned in Java and C# and introduce the object orientation and exception handling mechanisms which are popular in those languages whilst retaining the unique, readable nature of COBOL.

The Core Ideas

  1. Exceptions are represented by objects.
  2. When something exceptional happens, an Exception object representing it is created and 'raised'.
  3. This Exception object works its way back up the program in the exact reverse order to the way the program worked its way to where the Exception was raised.
  4. If left to its own devices, the Exception will raise its way to the top of the program and stop the program from executing.
  5. To stop this happening and to generally 'handle' raised exceptions, we use a concept of 'catching' then with a catch clause.
  6. Sometimes, we need a piece of code to execute whether or not an exception has been raised before that code is reached. To achieve this, we use a finally clause.

The simplest way to create an object to represent an exception is to make it have the Exception type:

       01 myException type Exception.

We can set that exception to a new instance of an exception in the procedure code or using a value clause in the data division:

       01 myException type Exception.
       procedure division.
           set myException to new Exception("Something exceptional happened")
      
... or ...
       01 myException type Exception value new Exception(
           "Something exceptional happened")

The advantage of the first approach is that the message can be varied according to program logic:

       01 myException type Exception.
       01 eString type string.
       01 exceptionType binary-long.
       procedure division.
           evaluate exceptionType
              when 1
                  move "Level one woopsy happened" to eString
              when 2
                  move "Big problem" to eString
              when other
                  move "Panic now!" to eString
           end-evaluate
           set myException to new Exception(eString)

Now that we have some idea how we can create and raise exceptions, how about catching them? The code below shows a simple exception catching mechanism:

      * Catch an exception
       try
           set y to 0
           compute x = 10 / y
       catch ex 
           display ex.Message
       end-try

The above will catch a divide by zero exception. However, we do not need to catch the exception in the same method as where it is raised. The following shows how exceptions can raise out of one method and be caught in another one which calls it or is higher up the call chain:

       method-id caller.

           01 ex type Exception.
      * Catch an exception
           try
      * The called method will raise and exception
      * and not catch it, so we can catch it here instead
               invoke self:::called
           catch ex
               display ex::Message
           end-try
       end method.

       method-id called.
           01 y as binary-long.
           01 x as binary-long.
           set y to 0
           compute x = 10 / y
       end method.

The process of the exception 'bubbling up' will continue until it is caught. For example:

       method-id caller.
           01 ex type Exception.
      * Catch an exception
           try
      * The called-again method will raise and exception
      * and not catch it, so we can catch it here instead
               invoke self:::called
           catch ex 
               display ex::Message
           end-try
       end method.

       method-id called.
           invoke self::called-again
       end method.

       method-id called-again.
           01 y as binary-long.
           01 x as binary-long.
           set y to 0
           compute x = 10 / y
       end method.

One really powerful feature of exception handling in Micro Focus Managed COBOL is that we can catch different types of exceptions in different places. This makes the layout of the logic in the code very simple:

       01 numb-in pic 9.

       01 ex1 type LowException.
       01 ex2 type HiException.
       accept numb-in
       try
          evaluate true
              when numb-in < 3 
                  raise new LowException("Number too low")
               when numb-in > 8
                   raise new HiException("Number too hi") 
               when other
                   invoke self::doSomething(numb-in)
           end-evaluate
       catch ex1
           display "You put in a number < 3"
       catch ex2
           display "You put in a number > 8"
       end-try     Finally, we can look at Finally.
      01 numb-in pic 9.
      01 ex1 type LowException.
      01 ex2 type HiException.
      accept numb-in
      try
          evaluate true
              when numb-in < 3 
                  raise new LowException("Number too low")
               when numb-in = 8
                   raise new EightException("Eight is illegal")
               when numb-in > 9
                   raise new HiException("Number too hi") 
               when other
                   invoke self::doSomething(numb-in)
           end-evaluate
       catch ex1
           display "You put in a number < 3"
       catch ex2
           display "You put in a number > 9"
       finally
           display "Bye Bye"
       end-try

In the above example, the Bye Bye display will always happen. The code in the finally block will occur whether or not an exception is raised and/or caught. This is a trivial example; serious examples include things like closing files or hiding windows in GUI applications.