COBOL developers like other Developers have for years used various techniques to identify and handle issues when processing yields results that are unexpected during execution of their code. While the techniques vary in each shop there is a technique that is more widely used in the .NET environment that COBOL developers should look at and consider. The technique is referred to by a number of names or phrases such as 'throwing exceptions', 'raising exceptions' or simply 'exceptions'. While it can be a more standard way of identifying and handling errors that occur, exception processing is not without some overhead that developers must be aware of and take into consideration when deciding how to handle non-standard results from execution. Visual COBOL provides mechanisms to enable COBOL developers to take advantage of the same exception handlers that distributed developers have been doing for years.
Let's start by taking a look at a simple and pretty standard COBOL way of handling exceptions. We'll then see how that same example would be coding in a managed environment utilizing Visual COBOL.NET.
Standard COBOL Error Handling
In COBOL shops developers use whatever technique is most widely used and accepted in their environment. Most developers plan for and take action to identify what would be called standard errors. Standard errors refers to the type of issues that may be expected to be encountered such as missing data, invalid data, or improperly formatted data. Checking for this type of error is common and expected and developers know how to do this with their coding techniques. Even in the .NET arena standard checks for missing data are common and are not considered exceptional.
So what would be considered exceptional errors? One example would be a missing file that is supposed to be present. When the application was created it was part of the design specification that a file needed for processing would always be present. But what if it isn't? This would be an exceptional condition and one in which 'special' error handling must be created for.
Declaratives are generally used in shops to denote when exceptional errors have occurred and are also used to handle these exceptional errors. The technique can be as simple as the following.
Notice the header 'Declaratives'. This is the area where you typically define an action that would occur for each exceptional error code encountered. Continuing our example from above, we expect a file to be present when the application starts. The code shows a check for a 'File Not Found' exception. Since we always expect a file to be present this would be an exceptional condition and processing cannot continue.
Now let's see how to do this in a managed .NET environment with Visual COBOL.
Throwing things around
In a .NET environment when unexpected processing occurs an 'exception is raised' or 'we throw an exception'. The terms are synonymous with error handling in the distributed world so you may want to get used to them. Throwing an exception in Visual COBOL is really straightforward and thanks as you'll see to intelli-sense is easy to code up.
Let's take our previous example and see how to recode it for .NET.
We've used two techniques to raise the exception. For the file status of '35' we used the instantiation method to establish an exception object. We first define an exception object in Working-Storage:
Next we instantiate (or create a working version within our run-unit) the object and populate it. Once we have populated the object with the necessary information we 'raise' the exception to the run-unit. This is accomplished by the following lines of code:
The other mechanism we used was for the 'other' condition. In this instance we did not instantiate a specific object, but rather we simply raised an exception with a specific error message.
Both methods are valid and each accomplishes our goal of raising an exception. The first method however creates an object that we can then reuse at some later point in time if we so chose to. The first method though also adds additional overhead to the run-unit in not only creating the object, but maintaining it.
As we've just seen, the .NET method of throwing exceptions is quite straightforward and easy to implement in Visual COBOL. There are some caveats though you should be aware of. In general, raising an exception is just staggeringly inefficient. The program has to populate the stack trace when the exception is raised and this is generally really slow. It is quite literally thousands of times faster to trap a condition with an 'on' clause or an 'if' statement than to utilize exception handling. Back in the early Java days the mantra was:
"Never raise an exception for something you expect to happen".
So, if we expect empty strings to happen sometimes then that is not an exception, rather it is an expected condition and an issue that needs to be handled and addressed in standard coding techniques for the application. In our example we expect a file to be present and if none is found then we should by all means raise an exception. We expect users to enter invalid data though so these would not be exceptions but would rather be standard input errors we would trap for in our application source.
The attached zip file contains two solutions, Declaratives and Exceptions. The Declaratives solution is the standard manner in which COBOL developers have raised exceptions. The Exception solution is a managed Visual COBOL solution using the technique described above. Experiment with both solutions and see how to adapt this technique to your environment.
Exception handling in the distributed world can be quite a powerful tool for a developer. It provides a standard mechanism in which exceptions are identified, presented and dealt with. Caution should be used however when implementing exception handling to only handle those conditions that are truly exceptional and not expected in the normal course of processing.