Collections, Intrinsics and Dictionaries Tutorial (UNIX) | Requirements-based Vocabulary 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:
Time to complete: 15 minutes
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
anim bank3
Animator starts with the first statement of bank3.cbl highlighted ready for execution.
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.
move "Mike"
to aCustomer
).
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.
invoke self "initializeClass"
).
Execution switches to the "initializeClass" method of the Account class.
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.
exit method
statement.
Now the class initialization code is has executed, control passes to the start of the "openAccount" method of the HighRateAccount class.
if lsInitialValue
< 1000
).
The test succeeds, indicating an exception condition.
invoke ExceptionManager
"queryMessageFile"...
).
This message returns the offset for Account class exception numbers.
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.
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.
In the next session we will look at how you can register an exception handler to provide different behavior for handling exceptions.
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:
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
anim bank3
Animator starts with the first statement of bank3.cbl highlighted ready for execution.
invoke AccountExceptionHandler
"initializeHandlers"
).
Execution switches to the "initializeHandlers" method of AccountExceptionHandler.
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.
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.
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.
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.
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
acexhand is the executable program for the AccountExceptionhandler class.
Execution halts inside the "onExceptionAccountError" method of AccountExceptionHandler.
set lnkReturnObject
to null
).
The parameter lnkReturnObject
is ultimately
returned as the object reference to the account the application is
attempting to create.
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.
subtract lsOffset
from....
).
The result in lsException corresponds to the exception numbers defined in the error message file.
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.
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.
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.
This concludes this tutorial on exception handling.
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.
Collections, Intrinsics and Dictionaries Tutorial (UNIX) | Requirements-based Vocabulary Tutorial (UNIX) |