Error Handling Routines
In This Chapter
This chapter explains how to write an ALGOL error handling routine.
Overview
DBGenFormat supports error handling routines that analyze, log, and display errors and determine how Databridge Accessories respond to those errors.
To use an error handling routine, you must write a patch file containing the error handling code and specify the error handling routine in the DBGenFormat parameter file.
Whenever an error occurs, the Databridge Accessory calls the DBERRORMANAGER entry point in DBSupport. The error manager procedure calls the user-written error handler to analyze the error and handle it. For example, the error handling routine might write the error to a log, send an e-mail message, or reload a missing audit file. It then returns an EMATYPE value that tells the Accessory what to do: ignore, retry, or fail.
Note
If you do not use an error handler patch, the default error handler in DBSupport returns DBV_Default to the Accessory, indicating that the Accessory can decide whether the error is fatal, should be retried, or should be ignored.
DBERRORMANAGER returns the following EMATYPE values:
EMATYPE | Description |
---|---|
DBV_Default | The Accessory decides what to do with the error. |
DBV_Fatal | The Accessory terminates. |
DBV_Ignore | The Accessory ignores the error and continues. |
DBV_Retry | The Accessory retries the operation. |
Error handling routines must use the DBErrorManagerHead heading defined in SYMBOL/ DATABRIDGE/INTERFACE. While the patch file must be written in ALGOL, the error handling routine could call a COBOL program to perform the actual error handling.
The patch file can contain declarations global to the error manager procedure. See the sample error manager patch called PATCH/DATABRIDGE/SAMPLE/SUPPORT/ERRORHANDLER.
Writing an Error Handling Routine
To write an error handling routine, complete the following steps:
- Read this entire chapter so that you get an understanding of what you can make your error handling routine do. For instance, the error handling routine can do the following:
- Determine what errors the Accessory can handle
- Determine what the Accessory can do in response to errors (analyze them, log them, display them, continue processing, terminate, and so on)
- Familiarize yourself with the error handling sample in Sample Error Handling Routine.
-
Use CANDE or another editor to retrieve the DBGenFormat parameter file DATA/GENFORMAT/SAMPLE/CONTROL.
For a general description of the DBGenFormat parameter file, refer to the Databridge Host Administrator's Guide. 4. Rename the file, as follows:
DATA/GENFORMAT/databasename/CONTROL
where databasename is the name of the database for which you are creating the error handling routine.
Note
If your error handler does not use any database-specific information and you do not need a tailored DBSupport library for any other reason, (for example, because you use filler substitutions) you can put the error handler routine in the non-tailored DBSupport library.
In this case, skip this step, save DATA/GENFORMAT/SAMPLE/CONTROL found in step 6 below, use START WFL/DATABRIDGE/COMP ("SUPPORT") in found in step 8, and skip step 9.
-
Declare the patch file that contains the error handling routine, as follows:
ERROR MANAGER errormanagername IN "patchfiletitle"
where errormanagername is the name of the error handling routine and patchfiletitle is the name of the patch file that contains the error handling routine. 6. Save
DATA/GENFORMAT/databasename/CONTROL
. 7. Write the error handling routine.A sample error handling routine is described in Sample Error Handling Routine. 8. Compile the tailored support library, as follows:
START WFL/DATABRIDGE/COMP ("SUPPORT", "databasename" ["logicaldatabasename"])
Where Is "SUPPORT"
The literal that represents the DBSupport library
The quotation marks are required."databasename" The name of the database for which you are creating the tailored support library
The database name can include a usercode and pack, which are used to locate the database DESCRIPTION file, as follows:"(usercode)databasename ON packname"
The quotation marks are required."logicaldatabasename" The name of a logical database for which you are creating the tailored support library This WFL compiles layout tables for each data set in the database designated by databasename or logicaldatabasename. This results in the new tailored support library titled as follows:
OBJECT/DATABRIDGE/SUPPORT/databasename
— or —
OBJECT/DATABRIDGE/SUPPORT/databasename/logicaldatabasename
These data set-specific layout tables contain the offsets and sizes of individual data items.
Caution
If you have two databases with the same name under different usercodes, and you are running Databridge from a third usercode, be careful when you create a tailored support library. In this case, the second library you compile overwrites the first, because Databridge strips the usercode and pack name from the database name to create the tailored support library title.
-
In the Accessory parameter file, enter the tailored support library name for the SUPPORT option as follows:
For Do this Databridge Clients In the DBServer parameter file, enter the tailored support library name for the SUPPORT option.
For more information, refer to the Databridge Host Administrator's Guide.Other Accessories In the Accessory parameter file, enter the tailored support library name for the SUPPORT option.
For more information, refer to the Databridge Host Administrator's Guide.
What to Do Next
You can now use your error handling routine and run your Databridge Accessories as usual.
Sample Error Handling Routine
The sample error handling patch PATCH/DATABRIDGE/SAMPLE/SUPPORT/ERRORHANDLER, does the following:
- Uses the DBErrorManager head included in SYMBOL/DATABRIDGE/INTERFACE and documented in the Types, Values, and Array Layouts section of this guide.
- Writes the error message to the system SUMLOG if the Accessory is privileged, otherwise, it displays the message.
-
Determines whether or not a missing audit file caused the error, and if that is the case, starts a WFL to recopy the missing audit file. Then the error handler returns DBV_Retry to the Accessory to indicate that it should retry whatever it was doing when it got the error message.
The ALGOL source code for this example is as follows.
Note
Read through this patch carefully before implementing it. Its main purpose is to illustrate ways to handle errors as a basis for writing your own custom error handling routine.
This routine uses a job called WFL/RELOAD/AUDIT, to copy an audit file, but WFL/RELOAD/AUDIT is not included on the Databridge release medium.
09000000
$ SET OMIT 09000100
###### ---------------------------------------------------------------------09000200
09000230
Module: PATCH/DATABRIDGE/SAMPLE/SUPPORT/ERRORHANDLER 09000240
09000250
Project: Databridge 09000260
09000270
Description: Databridge Example Error Handler patch 09000280
09000290
(c) Copyright 2019 Micro Focus or one of its affiliates. 09000390
09000530
---------------------------------------------------------------------09000540
09002000
Modification history 09002100
-------------------- 09002200
09002300
Version 41.471 09002400
1 Initial release. 09002500
09002600
Example error manager routine. This is a patch 09002700
to SYMBOL/DATABRIDGE/SUPPORT and can be included by inserting
09002800
the following declaration in DATA/GENFORMAT/<database>/CONTROL:
09002900
09003000
ERROR MANAGER ERRORHANDLER 09003100
IN "PATCH/DATABRIDGE/SAMPLE/SUPPORT/ERRORHANDLER" 09003200
09003300
Warning: Read through this patch carefully before implementing
09003400
it. Its main purpose is to *illustrate* some different ways to 09003500
handle errors, including writing to the SUMLOG and starting a 09003600
job called WFL/RELOAD/AUDIT, which is not part of the release, 09003700
to copy an audit file from somewhere. 09003800
09003900
Use this patch as a basis for writing your own custom error 09004000
handling routine. If all you want to do is display error 09004100
messages then simply use the default error handler that is 09004200
built into DBSupport. 09004300
09004400
End History 09004500
$ POP OMIT 09004600
70004700
70004800
boolean IAmPrivileged; 70004900
70005000
array ErrScratch [0 : 29]; 70005100
interlock 70005200
ErrorHandlerLock; 70005300
70005400
DBErrorManagerHead [ErrorHandler]; 70005500
% ------------ 70005600
70005700
begin 70005800
own boolean 70005900
Initialized; 70006000
70006100
procedure Initialize; 70006200
% ---------- 70006300
begin 70006400
IAmPrivileged := DBPrivileged; 70006500
70006600
Initialized := true; 70006700
end Initialize; 70006800
70006900
procedure LogComment; 70007000
% ---------- 70007100
begin 70007200
% Write a comment to the SUMLOG. 70007300
% The log entry will look like: 70007400
% SETSTATUS CALL: LC : DBTwin: DBM116: Unknown filter 70007500
% name: EXAMPLE2. 70007600
70007700
define LenLoc = 2 #; 70007800
define pLogStart = pointer (ErrScratch [LenLoc + 1]) #;70007900
define Build = replace pLog : pLog by #; 70008000
pointer pLog; 70008100
boolean SSResult; 70008200
70008300
pLog := pLogStart; 70008400
$ set omit 70008500
case AccessoryID of 70008600
begin 70008700
DBV_Span: 70008800
Build "DBSpan"; 70008900
DBV_Snapshot: 70009000
Build "DBSnapshot"; 70009100
DBV_Server: 70009200
Build "DBServer"; 70009300
DBV_Tanker: 70009400
Build "DBTanker"; 70009500
DBV_Lister: 70009600
Build "DBLister"; 70009700
DBV_Twin: 70009800
Build "DBTwin"; 70009900
DBV_GenFormat: 70010000
Build "DBGenFormat"; 70010100
DBV_AuditTimer: 70010200
Build "DBAuditTimer"; 70010300
DBV_TwinInit: 70010400
Build "DBTwinInitialize"; 70010500
else: 70010600
Build "Accessory"; 70010700
end; 70010800
$ pop omit 70010900
Build ": ", pErrMsg for ErrMsgLen; 70011000
70011100
ErrScratch [0] := LenLoc; % location of length word 70011200
ErrScratch [LenLoc] := offset (pLog) 70011300
- offset (pLogStart); 70011400
SSResult := SETSTATUS (2, 26, 0, ErrScratch); 70011500
end LogComment; 70011600
70011700
70011800
EMATYPE procedure AuditUnavailable; 70011900
% ---------------- 70012000
70012100
% If the problem is a missing audit file, we'll run a 70012200
% WFL job to recopy it. 70012300
70012400
begin 70012500
pointer pAFN; 70012600
integer AFN; 70012700
real Rem; 70012800
real Len; 70012900
boolean MissingFile; 70013000
70013100
% Scan the error message to find the AFN and determine 70013200
% if the problem is that the file is not found. 70013300
70013400
pAFN := pErrMsg; 70013500
Rem := ErrMsgLen; 70013600
while Rem > 0 do 70013700
begin 70013800
scan pAFN : pAFN + Len for Rem : Rem - Len 70013900
while = " "; 70014000
scan pAFN for Len : Rem 70014100
until = " "; 70014200
Len := Rem - Len; 70014300
if Len > 0 then 70014400
begin 70014500
if pAFN in Numbers for Len then 70014600
begin 70014700
AFN := integer (pAFN, Len); 70014800
end 70014900
else 70015000
if pAFN = "not found" then 70015100
begin 70015200
MissingFile := true; 70015300
end; 70015400
end; 70015500
end; 70015600
70015700
if MissingFile then 70015800
begin 70015900
replace pointer (ErrScratch) by 70016000
"START WFL/RELOAD/AUDIT (", 70016100
AFN for * digits, ")", 0; 70016200
zip with ErrScratch; 70016300
70016400
% Tell Accessory to retry 70016500
70016600
AuditUnavailable := DBV_Retry; 70016700
end; 70016800
end AuditUnavailable; 70016900
70017000
70017100
lock (ErrorHandlerLock); 70017200
70017300
if ^ Initialized then 70017400
begin 70017500
Initialize; 70017600
end; 70017700
70017800
% If we are running under a privileged usercode, we 70017900
% can write it directly to the SUMLOG, else we'll do 70018000
% a simple display. 70018100
70018200
if IAmPrivileged then 70018300
begin 70018400
LogComment; 70018500
end 70018600
else 70018700
begin 70018800
display (pErrMsg); 70018900
end; 70019000
70019100
unlock (ErrorHandlerLock); 70019200
70019300
% Check for missing audit file. 70019400
70019500
if ErrNbr = DBM_AUD_UNAVAIL then 70019600
begin 70019700
ErrorHandler := AuditUnavailable; 70019800
end; 70019900
end ErrorHandler; 70020000
70020100
% End of ErrorHandler patch 70020200
70020300