Default error handling - ERRORSYS.PRG and XPPERROR.LOG Foundation
The default error handling of Xbase++ is implemented in the ERRORSYS.PRG file. It contains the function ErrorSys() which installs the default error code block at program startup. When a runtime error occurs, information about the error is displayed on screen. Depending on the error condition, the user can decide whether to ignore the error, retry the last operation or terminate the program.
In case of program temination an error log can be created optionally which gets written to the XPPERROR.LOG file. The error log contains important data about the error condition and provides the developer with valuable information. The situation when the error occured can be analyzed in detail which allows a programming error to be identified directly or helps to localize the error using the Xbase++ debugger. Information that may get listed in the error log is too numerous to describe. Therefore an example of an error log is discussed below. It explains how to interprete information contained in the log file. The example originates from the MDIDEMO sample program which is part of the Xbase++ installation.
The error log begins with version information about Xbase++ and the operating system. Two main sections follow: the contents of the error object and the call stack. The call stack lists the sequence of calls to functions, procedures or methods that has led to the error condition. The function name is followed by the line number of the PRG file where the function is called. In the example, the error log is initiated in line 155 of the StandardEH() function. This function is called from a code block which is programmed in line 24 of ErrorSys(). Both functions are part of the ERRORSYS.PRG file and implement the default error handling of Xbase++. They do not contribute to a runtime error but are part of the call stack when the error log is created. The runtime error occured in line 230 of the OpenCustomer()function which is programmed in the MDICUST.PRG file. The call stack clearly identifies the program line that raises the runtime error. It cannot display the name of the PRG file, only line number and function name.
If the information contained in the error object is not sufficient to clearly identify a programming error, the error situation can be analyzed easily with the Xbase++ debugger. For this, the application must be started from the debugger and a break point must be set on line 230 of the MDICUST.PRG file.
In this example, however, the error object provides sufficient information to identify the error: the CUSTOMER.DBF file could not be found. The following code has raised the runtime error:
This line of code is translated by the preprocessor and the actual code executed at runtime looks like this:
In its instance variable :operation, the error object contains a string with the name of the failed operation or function, respectively, and the instance variable :args contains all arguments or formal parameters passed to the function. The error log lists data types and values of the arguments (VALTYPE and VALUE). The instance variable :descriptiongives a short description of the failed operation. In the example, the error is raised by the operating system, not by the Xbase++ application. This is also indicated by the instance variable :osCode which contains the value 2 in this case. If this instance variable contains a number not equal to zero, then this is an operating system error code.
Another important information is stored in the :genCode instance variable. It is the generic Xbase++ error code that corresponds to #define constants found in the ERROR.CH file. The number 40 shown in the example equals to the constant XPP_ERR_DOS and indicates the error to be raised by the Disk Operating System.
Summary
The error log records the contents of an error object together with the call stack. The call stack indicates WHERE a runtime error occured while the error object provides information WHY it is raised. In many cases the contents of the instance variables :arg, :description, :operation, :osCode and :genCode are sufficient to clearly identify and resolve a runtime error (please refer to the reference documentation for a description of other instance variables of the error object).
Fatal errors - XPPFATAL.LOG
If a fatal error occurs that is not possible to be handled by the default error handling system, the Xbase++ runtime kernel creates the file XPPFATAL.LOG in the current directory. This file contains information about what happened and where the fatal error occurred, and should be sent to Alaska Software for "forensic" analysis.
Note that the XPPFATAL.LOG file is also created when an application is terminated by pressing Alt+C. In this case, do not send XPPFATAL.LOG to Alaska Software.
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.