Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / COBOL

Exception Handling In Micro Focus Managed COBOL

0.00/5 (No votes)
19 May 2010CC (ASA 2.5)2 min read 12.7K  
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.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-ShareAlike 2.5 License