(Base One logo) .NET database and distributed computing tools

BFC | Visual Studio | Database Technology | Distributed Computing | Utility Classes

Advanced Error Handling
and Diagnostic Facilities

Error Handling

As an example of why the Base/1 Foundation Components Library (BFC) exists, take the case of error and exception handling. Half of all programming time can easily be burned up dealing with those things that are never supposed to happen, but do. Before BFC, whenever programmers looked for help, all they got was: "Error handling left as an exercise" or "Error handling details omitted to save space". Unfortunately, most software vendors prefer to relegate the subject of error handling to an appendix (if you're lucky).

Why? Because each software vendor, be it Microsoft, Oracle, Sybase, IBM, etc., is only interested in its own errors and not other causes. Meanwhile, BFC was originally developed specifically for creating defect- free database applications.

Throughout the Base/1 application framework, you'll find comprehensive error and exception handling features, with meaningful messages and automated recovery from failures. BFC's error handling mechanism lets you quickly find and correct errors, including failures that happen in production (after testing is done). When a mistake is made, like misspelling the name of a record field in a data base query, you're immediately notified of the error and the place where it occurred. In addition, production errors like "the line went down", "the hard disk disappeared" or "the bank's closing procedures were accidentally started before the foreign exchange rates came in" are handled either automatically or quickly and simply with BFC.

What programmers need are fast, clear explanations for errors regardless of where they originate and whether the causes are programming mistakes, software package bugs, hardware failures, corrupt data, or whatever. When working under the pressure of a tight deadline or the crash of a crucial production system, programmers don't want to have to search through a pile of different manuals to find the one needed for some particular error code to even begin to understand what went wrong.

We've gone through the key manuals, organized the error causes, and turned each into a meaningful message, regardless of who is the culprit. Instead of letting your application crash from the unexpected, BFC provides a soft landing, with a screen full of useful information: where was the failure, what function was executing at the time, what object detected the problem, and often, an error hint. The error hint shows information like what database query was being attempted, which is often enough to guide a programmer to an immediate solution instead of having to painstakingly try to reproduce and locate the problem.

BFC's error handling mechanism lets programmers quickly find and correct errors, including failures that happen in production (after testing is done). When a mistake is made, like misspelling the name of a record field in a database query, the programmer is immediately notified of the error and the place where it occured. In addition, production errors like "the line went down", "the hard disk disappeared" or "the bank's closing procedures were accidentally started before the foreign exchange rates came in" are handled either automatically or quickly and simply with BFC.

The basic mechanism for trapping and displaying errors, cleaning up after errors, and making sure things are always left in an acceptable state is efficient and complete enough to put in production. Thus, the same error handling that serves programmers is also used in the production environment for notification of hardware and operation errors. By using identical error and recovery paths in development and production, programmers automatically test the production error handling mechanism as a natural consequence of their development work, leading to more dependable applications.

BFC's generic, integrated error handling facility is based on a unified set of return codes and associated messages. Application programmers have the option of adding their own error codes and messages to BFC's, immediately gaining the benefits of automated cleanup and recovery from failures. In addition, you can alter BFC's default error-handling to provide, for example, a custom message or behavior for a particular error. Programmers are free to decide whether to piggyback on BFC's error facility, build their own, or do both.

Untrapped errors will invoke the Screen Manager Class's AbandonShip() processing, which assures meaningful error messages and orderly shutdown of the application. AbandonShip processing has two main objectives: first, provide error information in a modal dialog, dlgAbandonShip; second, do whatever cleanup is required for a graceful, damage-free landing. The top priority is to prevent the types of hard crashes which might either corrupt data or hang other users.

Abandon Ship Dialog (with Error Hint showing SQL that failed)

Abandon Ship Dialog

  • Rich Client applications include a comprehensive error and exception handling mechanism with meaningful messages and hints that help to quickly find and fix bugs.
     
  • Untrapped errors invoke the AbandonShip() processing, and bring up the above dialog box. It shows you the exact error spot, the function that was executing and often a sufficient error hint to locate the problem code. Also, it insures the orderly shutdown of the application.
     
  • Programmers can add their own error codes and messages to BFC’s and gain the benefits of automated cleanup and recovery from failures.

During AbandonShip processing all database connections are closed, as are open files (through special processing in clsFile, a Utility library class found in B1UCFil.h & cpp). No attempt is made to cleanup memory that has been dynamically allocated by the user, such as strings and database record buffers, because memory leaks during abnormal termination are a relatively benign side-effect. Neither is any attempt made to give the end user one last chance to finish the current operation, which may have built-in logical traps.

The application programmer is always free to Try/Catch errors and do any special handling desired instead of terminating the application. However, since for normal processing BFC functions always return completion codes instead of throwing errors, programmers usually find few instances where they feel compelled to code Try/Catch blocks.

To put out a different AbandonShip dialog, for example, with a more detailed, user-friendly message, it's simplest to allow AbandonShip processing to take place and override the final display step. You can override the DispAbandonShip() function to display a custom tailored dlgAbandonShip. This allows you to cause, during abnormal termination, an application specific dialog box to come up whose contents is appropriate for the particular error.

The AbandonShip dialog has been designed to make it convenient to provide an error report that is sufficiently detailed to be useful. A user can take a screen snapshot of it and then drag it aside and take another screen shot of the application as it looked right before the error. (These screen snapshots can be pasted into MS Word, for example, and then attached to an email report of the problem.) If the Error Hint in the Abandon Ship dialog is too long to be completely visible without scrolling (for example, a lengthy SQL statement that failed), the hint can also be separately highlighted, copied, and pasted into the problem report.

The Utility library provides classes for handling return codes and associated exceptions, including:

  • clsUtilException (utility exception class)
  • clsRetCodInfo (return code information class)

In a typical BFC application, any Utility Exception class (clsUtilException) or other exception that is not handled is caught by the framework, the AbandonShip dialog is displayed, and the application is terminated cleanly. Putting a BREAKPOINT in the clsUtilException function gFn_ThrowUtilException() is especially helpful. You can then look at the call stack at exactly the point where the problem occurs.

The Utility Exception class (clsUtilException) handles most but not all types of errors. For example, a third party library might throw and not handle a type of error not known to BFC. Fortunately, the BFC error handling mechanism catches it - but doesn't know what to do with it. You can override the default complaint of "unknown error" and process the exception yourself.

Programmers can also make use of the same macros BFC employs for displaying Error File Name and Line Number during abnormal termination.

Duplicate Data and Foreign Key Errors

The error handling mechanism also provides additional useful information when some common data entry errors occur. Applications can obtain a comma separated list of the offending field(s) whenever duplicate data and foreign key errors are encountered. The offending constraint or index name is converted to the more understandable field name or list of field names responsible for the error.

Normally the database error messages returned from back-ends are cryptic, such as "Unique constraint CONSTRAINT_XXX violated". Programs can obtain a field list and that information can be used to display more meaningful error messages to the user, and even put back the focus and highlight the offending field on the screen.


Diagnostic Facilities

BFC not only supports the tracing and debugging features of the Visual Studio development environment, but also we've added low-level facilities, such as database activity tracing, plus extra documentation to help you get the most out of Microsoft's programming tools.

BFC goes a long way towards eliminating two major C++ bugaboos: memory leaks and memory overwrites. A BFC application built in Debug mode (as opposed to Release mode) automatically leverages MFC memory diagnostic facilities to detect these programmer errors.

In addition, BFC adds a number of diagnostic capabilities that make debugging even easier:

  • Application programmers can extend BFC's standard error handling classes and functions with their own error and completion codes and customized messages.
  • The BFC Command Processor can be run interactively in a single-step mode of execution.
  • BFC's Distributed Batch Processing Services can record a detailed log of batch job progress information and completion codes.
  • BFC provides a full database trace facility for debugging and resolving performance problems. You can trace through any BFC MFC, COM or .Net application displaying or logging all database function calls, the values of passed parameters, SQL statements, and processing start and completion times.

Trace Facility (showing User Master screen & Oracle OCI calls)

Trace Facility (showing User Master screen)

  • Rich Client applications can allow tracing of database activity to a very low-level.

Five tracing options provide different levels of detail, and you can start and stop tracing at any point to collect just the information you need. If an error occurs and an AbandonShip (severe error) dialog is displayed, the trace window will be available at the same time as the dialog is displayed. The trace can be saved to a file at any point.

The real strength in the Base/1 diagnostic facilities comes from BFC's general approach to error handling, which practically eliminates the need for the usual tracing and debugging tools. BFC classes for error handling and tracing have saved untold amounts of wasted debugging time, while improving the reliability and performance of applications in production. That is to say nothing of how glad programmers have been to avoid tedious, unrewarding hours of tracking down the causes of the same types of bugs and performance problems, over and over.


BFC | Visual Studio | Database Technology | Distributed Computing | Utility Classes


Home Products Consulting Case Studies Order Contents Contact About Us

Copyright 2012, Base One International Corporation