PreviousCollections, Intrinsics and Dictionaries Tutorial (UNIX) Requirements-based Vocabulary Tutorial (UNIX)Next"

Chapter 17: Exception Handling Tutorial (UNIX)

This tutorial shows you how to use the exception handling mechanism available in the Object COBOL Class Library. An exception is raised by an object whenever it traps an error. This tutorial contains the following sessions:

  1. Raising an Exception

  2. Registering an Exception Handler

  3. Writing an Exception Handler

Time to complete: 15 minutes

17.1 Raising an Exception

An object raises an exception when it has trapped an error. The objects in the supplied class library define approximately ninety exception conditions altogether.

An object raises an exception by sending itself the "raiseException" message, passing an error number as a parameter. The Base class implements the "raiseException" method, so it is inherited by all objects.

The error number is used to identify a message from an error file; it is also passed to an exception handler for the object if one is registered.

We will use the Account classes introduced in the previous tutorial to show you how to raise and trap exceptions. When an account object traps an error, it responds by raising an exception. For example, attempting to open a high rate account with an initial balance of less than $1000 is an error condition.

To animate error raising code

  1. Change to the directory with the Object COBOL demo programs (by default $COBDIR/demo/oops).

  2. Run the supplied shell script exepscrp to compile all the programs and classes needed for this tutorial.

  3. Start animating bank3.cbl. Enter the following command line:

    anim bank3

    Animator starts with the first statement of bank3.cbl highlighted ready for execution.

  4. Move the text cursor down to the first statement below tag B010 (move "Mike" to aCustomer), and press the Rst Cursor-position keys.

    The first statement in this program registers an exception handler. You will look at this code later in this tutorial, so for now we skip over it.

  5. Step the statements below tag B010 (move "Mike" to aCustomer).

  6. Step the statement below tag B020 (invoke HighRateAccount "openAccount"...).

    This is the first message sent to the HighRateAccount class, so before executing the "openAccount" method, the class initialization code is run. The execution point appears inside the Procedure Division of the HighRateAccount class.

  7. Step the statement below tag H000 (invoke self "initializeClass").

    Execution switches to the "initializeClass" method of the Account class.

  8. Step the statement below tag A000 (invoke ExceptionManager "registerMesageFile"...).

    The account classes have their own set of exception numbers, and their own set of error messages. The "registerMessageFile" message sets up an error message file of account.lng, contained in the appropriate COBOL default language directory. The directory searched depends on the setting of the $LANG environment variable. The way you compile and package error files is described in the chapter Exception Handling Frameworks.

    Each exception must have a unique numeric identifier, but when you write an error message file for a set of classes, you don't necessarily know what application those classes will be used in, and what other message files will be in use.

    The registration mechanism provided by the ExceptionManager enables you to number your messages starting from 1. Then, when you register a message file you are returned an offset. Each message is then identified by adding its number in the file to the offset to create a unique exception number. We don't need to store the offset, since we can fetch it from the ExceptionManager when it is needed.

  9. Step the exit method statement.

    Now the class initialization code is has executed, control passes to the start of the "openAccount" method of the HighRateAccount class.

  10. Step the statement below tag H010 (if lsInitialValue < 1000).

    The test succeeds, indicating an exception condition.

  11. Step the statement below tag H011 (invoke ExceptionManager "queryMessageFile"...).

    This message returns the offset for Account class exception numbers.

  12. Step the next statement (add insufficientFundsForAccount...).

    The exception numbers are all defined as level-78 data items in copyfile accinfo.cpy. Adding the exception number to the offset returned by the ExceptionManager gives us a unique exception number which the ExceptionManager can use to fetch the error message and display the error.

  13. Step the next statement (invoke self "raiseException"...).

    There is no exception handler registered for this object, so the ExceptionManager uses the default handler, which displays the error message and gives you the option to continue or terminate the program.

  14. Press T to terminate the application.

  15. Press Esc to exit Animator.

In the next session we will look at how you can register an exception handler to provide different behavior for handling exceptions.

17.2 Registering an Exception Handler

In the previous session, you saw how to raise an exception. This session shows you how you can register an exception handler for an object. An exception handler is a method which gets the exception number and the object raising the exception as parameters.

You can register an exception handler for a class or an instance object. If you register an exception handler against a class, then it is invoked for exceptions raised by all instances of the class as well as by the class itself.

Exception handler registration is a two step process:

  1. Create a CallBack for the exception method.

  2. Register the CallBack against an object with the ExceptionHandler.

Next you will animate through the code which sets exception handlers for the Account classes in the Bank application.

To animate the exception registration code

  1. Change to the directory with the Object COBOL demo programs (by default $COBDIR/demo/oops).

  2. Start animating bank3.cbl. Enter the following command line:

    anim bank3

    Animator starts with the first statement of bank3.cbl highlighted ready for execution.

  3. Step the statement below tag B000 (invoke AccountExceptionHandler "initializeHandlers").

    Execution switches to the "initializeHandlers" method of AccountExceptionHandler.

  4. Step the statement below tag E010 (invoke CallBack "new"...).

    This creates the callback for the exception handling method, "onExceptionAccountError", which is a method of self (the AccountExceptionHandler class). A callback is an object which represents a particular method in a particular object. For more information about CallBacks, see the chapter CallBack Frameworks.

  5. Step the statements below tag E020 (invoke ExceptionManager "register"...).

    This registers lsAccountError (the callback we just created) as an exception handler for the Account class. Any exceptions raised by the Account class or instances of the Account class will be passed to this method.

  6. Step through the remaining statements up to and including exit method.

    These register the same exception handler for exceptions raised by the other account classes. The execution point is now set to the statement below tag B010 in bank3.

  7. Leave animator running. The next session carries on directly from this one.

In the next session, you will look at the exception handler method, and see how it deals with an exception raised by the account classes.

17.3 Writing an Exception Handler

This session shows you how to write an exception handler method to deal with exceptions raised by an object. The method you write should have an interface like the one shown below:

 method-id. "errorMethod".
 ...
 linkage section. 
 01  errorNumber              pic x(4) comp-5.
 01  errorObject              object reference.
 01  aParameter               object reference.
 procedure division using errorNumber errorObject
                returning aParameter 
 ...
 exit method.
 end method "errorMethod".

The parameter returned from your exception handler can be used by the method which raised the exception. For example, our example exception handler returns a null object handle when an attempt to open an account fails. The "openAccount" method code in the HighRateAccount class which raises the exception returns the parameter from the exception handler in place of a valid handle to an account object.

Next you will animate the account exception handler. The instructions below assume that you are continuing this session directly from the previous one.

To animate the exception method

  1. Set a program breakpoint on the AccountExceptionHandler class.

    1. Push the keys: Env Program-break Select.

    2. Enter acexhand into the Enter Name of Program window.

      acexhand is the executable program for the AccountExceptionhandler class.

  2. Press the Zoom key.

    Execution halts inside the "onExceptionAccountError" method of AccountExceptionHandler.

  3. Step the statement below tag E030 (set lnkReturnObject to null).

    The parameter lnkReturnObject is ultimately returned as the object reference to the account the application is attempting to create.

  4. Step the statement below tag E040 (invoke ExceptionManager "queryMessageFile"...).

    So that the exception handler knows what action to take, it must extract the exception number from the exception id passed through to the method. The "queryMessageFile" message gets the offset value currently being used for account objects.

  5. Step the statement below tag E050 (subtract lsOffset from....).

    The result in lsException corresponds to the exception numbers defined in the error message file.

  6. Step the statement below tag E060 (if lsException < 4).

    The exception handler must now determine what type of exception has been raised in order to take the appropriate action. If the exception type isn't one it knows how to deal with, it reraises the exception (see the code below tag E080).

    More sophisticated exception handlers take different action depending on the type of exception; this exception handler simply categorizes account exception numbers between one and three as being those it understands, and those of four or greater as exceptions to be reraised.

  7. Step the statements below tag E070 (invoke ExceptionManager "errorMessage"...).

    This code fetches the error message (which is returned as a CharacterArray object) from the ExceptionManager and displays it. The only difference between this and the default exception handler is that this handler doesn't terminate the application. Push F2=View to see the message, and any other key to return to the Animator display.

  8. Step the code up to and including the exit method statement.

    Execution returns to the HighRateAccount class, at the point below the statement which raised the exception. The return parameter from the "raiseException" message is lsAccount - this was set to null by the exception handler. lsAccount is the result returned from the "openAccount" method, so the code which sent the "openAccount" message can test the handle returned - if it is null an exception has occurred.

  9. Step through the application until you see the Stop Run message from Animator.

  10. Push the Esc key to exit Animator.

This concludes this tutorial on exception handling.

17.4 Summary

In this tutorial you learnt how to:


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousCollections, Intrinsics and Dictionaries Tutorial (UNIX) Requirements-based Vocabulary Tutorial (UNIX)Next"