Chapter 23: Exception Handling Tutorial

This tutorial shows you how to use the exception handling mechanism available in the COBOL Base Class Library.

This tutorial uses Micro Focus alternatives and extensions to the ISO 2002 OO COBOL syntax.

This tutorial contains the following sessions:

  1. Raising an exception
  2. Registering an exception handler
  3. Writing an exception handler

Raising an Exception

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

The ExceptionManager class provides most of the logic for actually handling exceptions, including a default exception handler. The default exception handler displays an error message and shuts down the application when an object raises an exception, but an application can define its own exception handlers and attach them to individual classes or objects to redefine their behavior.

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 Bank application 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 debug exception raising code:

  1. Start the Net Express development environment.
  2. Click File > Open, and open Examples\Net Express IDE\Bank\resBank.app.
  3. Rebuild the project.

    Next you find the methods in the HighRateAccount class we want to step through, and set breakpoints on them.

  4. Display the Browse window: click Search > Browse
  5. Click the plus (+) sign next to base, then the plus (+) sign next to account and finally the plus (+) sign next to savingsaccount.
  6. Click highrateaccount in the left-hand pane, then openaccount in the right-hand pane.. This loads the OpenAccount method into the text editor.
  7. Set a breakpoint on the first statement of "openAccount", and also on the last statement.
  8. Click Debug > Start Debugging Click OK.
  9. Run the application.

    Control passes from the Debugger to the application.

  10. When the Bank window appears, open a High Rate Account with an initial balance of 0.00.
  11. Control returns to the Debugger.

    The execution point is on the first statement of the "openAccount" method.

  12. Step the first statement.

    The test succeeds. The HighRateAccount class has detected an exception condition.

  13. Step the next statement.

    The Account class registers a message file account.err the first time you create a new account (you can see the code which does this in the "setNextAccountNumber" method of the Account class). This contains error messages for the default exception handler to display. The registration allocates a range of error numbers to be used for account errors.

    The "queryMessageFile" message returns a numeric offset, giving the start of the range of error numbers.

  14. Step the next statement.

    The actual error number is defined by the level-78 data item, insufficientFundsForAccount, which matches the error number in the error file. A real application is likely to consist of classes from many sources, each of which has its own set of error messages.

    Adding the offset for the account error messages file (returned in the previous step) to the error number produces a unique error number from which the exception handler can identify both the error file and the message number.

  15. Step the next statement.

    This statement raises the exception.

  16. Click Debug > Run.

    When you send the "raiseException" message, the "raiseException" method in Base gets executed. This looks to see if this object has an exception handler registered.

    In this case, there is an exception handler registered for HighRateAccount objects, which displays a message box flagging the error.

  17. Click OK on the message box to dismiss it.

    Execution halts at the breakpoint on the exit method statement at the end of "openAccount". Execution always resumes at the point following the statement which raised the excepton, unless your exception handler closes down the application with a Stop Run statement (this is what the default exception handler does).

    In this case the exception handler sets the object reference returned to null; the part of the application which requests new accounts checks the reference for a null value so that it knows whether the "openAccount" was successful or not.

  18. Click Exit on the Bank window Account menu.

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

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 that receives 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 debug the code which sets exception handlers for the Account classes in the Bank application.

To debug the exception registration code

  1. Start the Net Express development environment.
  2. Click File > Open, and open Examples\Net Express IDE\Bank\resBank.app.
  3. Rebuild the project.
  4. Use the Browse window to find the "initialize" method of the BankApplication class (bankapp.cbl).
  5. Set a breakpoint on the first statement below tag B005.
  6. Click Debug > Run

    Execution halts on the breakpoint.

  7. Step the next statement.

    This creates the Callback for the exception handling method, "onExceptionAccountError", which is a method of self (the BankApplication instance).

  8. Step the next statement.

    This registers accountErrorMethod (the Callback for "accountError" in the BankApplication class) 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.

  9. Step through the remaining statements up to and including the Exit Method statement.

    These register the same exception handler for exceptions raised by the other account classes.

You have completed this section of the tutorial. Leave the Debugger in its current state as the next section carries on directly from this one.

Writing an Exception Handler

This section of the tutorial shows you how to write an exception handler method to deal with exceptions raised by an object. We will look at the exception handler the Bank application uses for dealing with exceptions from the account classes.

In the case of a failure to open a High Rate Account, the exception handler returns a null object handle to the "openAccount" method. The "openAccount" method code in the HighRateAccount class then returns the null object handle from the exception handler in place of a valid handle to an account object. The exception handler could be designed to do something else; for example, failure to open a High Rate Acount because of an insufficient initial investment could return a Savings Account instead.

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

  1. Find the statement below tag B100:
    1. Click Search > Find Text
    2. Enter B100 into the Find bar Text field.
    3. Click All on the Find bar

      You can remove the Find bar when you have finished by clicking View > Find bar

  2. Move the cursor down to the statement
    set nullReference to null

    and set a breakpoint.

    The effect is that execution stops whenver the account exception handler is invoked.

  3. Run the application.
  4. Open a High Rate account for James with an initial balance of 0.

    The HighRateAccount class raises an exception, and the Debugger stops on the first statement of the exception handler.

  5. Step the first statement.

    The parameter nullReference is ultimately returned as the object reference to the account the application is attempting to create. As you step through the execution you can see the path by which this parameter is returned.

  6. Step the next statement.

    The exception handler needs to verify that the error number it has received is of a type it knows how to deal with. It starts by getting the offset for account errors.

  7. Step the next statement.

    If the offset of this error matches the offset returned from the ExceptionManager, then the difference will be a number which corresponds to one of the error numbers for bank accounts.

  8. Step the next statement.

    This statement is part of the mechanism by which the business logic which deals with accounts signals the interface with information.

  9. Step the next statement.

    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 the When Other statement).

  10. Step the next statement.

    This is the exception which has been raised. The error numbers are all defined as level-78 data items in the copybook accinfo.cpy.

  11. Run the application up to the Exit Method statement.

    The Bank application displays a message box warning the user of the failure to create a new account.

  12. Click OK in the message box to dismiss it.
  13. Step the Exit Method statement.

    Execution returns to the Exit Method of the HighRateAccount "openAccount" method. You can see that the statement which raised the exception has lsAccount as a returning parameter; this has been set to null by the exception method we just executed.

  14. Step the Exit Method statement.

    The execution point is now on an End-Evaluate statement, back in the "onSignalOpenAccount" method of BankApplication. This code is aware of the possibility that an account may not have been created, and tests to see whether the object reference for the new account is null. If it is, execution jumps to the end of this method.

    When you build exception handling into an application, you have to remember that if you trap an exception successfully, execution will eventually resume at the same point it would have done if there had been no exception. Consequently, at points where an exception is possible your code must be able to check whether or not an exception has occurred. Checking whether you have been returned a null reference is one technique you can use.

You have now completed the tutorial on exception handling. You can stop the Debugger at any time.

Summary

In this tutorial you learned how to:


Copyright © 2009 Micro Focus (IP) Ltd. All rights reserved.