home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
PASCAL
/
TBTREE16.ZIP
/
ERROR.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-07-13
|
12KB
|
199 lines
(* TBTree16 Copyright (c) 1988,1989 Dean H. Farwell II *)
unit Error;
(*****************************************************************************)
(* *)
(* E R R O R H A N D L I N G R O U T I N E S *)
(* *)
(*****************************************************************************)
(* This unit is designed to handle a few of the errors which can occur within
TBTREE. Specifically, it handles I/O errors. Before explaining this unit,
I want to talk about the philosophy of error handling. There is a tradeoff
to be made when developing error handlers for a product such as TBTREE. I
could try to handle every possible error which could ever occur and try to
figure out what to do to handle the error. Although this would seem to
make it easier for the user of these routines, it would make my life very
difficult. More importantly, it would put a tremendous amount of overhead
into the program which would invariably slow it down, in most cases
unnecessarily. On the other hand, I could do no error checking whatsoever
which means that you must develop your application with error checking in
mind and preclude any errors from happening. In this way, you could
customize the error checking to your application and ensure that errors do
not occur. For example, you could make sure that you do not call my
routines with values which are out of range. This way, you only need the
overhead which is absolutely required and can handle errors in more of a
specific way. I have taken a middle of the road approach although I lean
more towards the second approach. There are certain types of errors which
I need to report to you to allow you to try to fix them. I/O errors fall
into this category. I supply a routine which gets called when an I/O error
occurs. This routine makes up the bulk of this unit. It is supplied as
part of this unit but is intended to be modified by the user as required.
You should set it up so that it handles errors in a manner which makes
sences in your application. The routine it self has further explanation.
When an error occurs and I call the routine, I pass back information which
can be used to solve the problem. When the routine is finished, it will
return back to where the error occurred. What happens then depends on the
error routine called. Again, further explanation accompanies the error
routine.
It should be noted that, like in previous versions, the bulk of the error
checking is up to you. You need to ensure that parameters are in range
before calls are made, indexes and data files exist before manipulating
them, file names are legal prior to creating a file, etc. *)
(* Version Information
Version 1.5 - Unit added to TBTREE
Version 1.6 - No Changes *)
(*\*)
(*////////////////////////// I N T E R F A C E //////////////////////////////*)
interface
type
RoutineNameString = String[50]; (* Used as type to provide the
routine name where the error
occured. Remember, these are
strings and are case
sensitive! *)
IOErrorRec = record
routineName : RoutineNameString;
tBTreeIOResult : Word;
end;
(*\*)
(* This routine will handle disk I/O errors which occur within TBTREE. Since
all disk I/O calls are concentrated either in the FILEBUFF unit or the PAGE
unit, this will trap all disk I/O error calls which occur. Errors are
trapped because I/O checking is turned off in the FILEBUFF unit and in the
PAGE unit. Instead, the Turbo Pascal routine IOResult is called after each
I/O operation. If a value other than 0 is returned, an error has occurred
and this routine is called. When the routine is called, the ioErrorRec
contains the name of the TBTREE routine which contained the error and the
error code returned as a result of the call to IOResult. Using this
information, you can decide what to do. You actually have two options.
First you can cause the program to terminate by either forcing an error or
by using Halt; The program will terminate after running through the exit
routines. If any exit routines do I/O (which they probably do) another
error could occur. If this happens, this routine will be called again. The
second option is to try to handle the error, depending on what it is. How
to correct the error is entirely up to you and your application. Once you
have solved the problem, your routine will terminate and control will
return to the place where the error occurred. The operation which caused
the error routine to be called will be repeated. If you solved the
condition which caused the error, the program will roll merrily along as if
no error ever occurred. If the error occurs again, this routine will be
called again. This will continue until you halt or fix the error
condition. As you can see, this could be the world's best infinite loop
generator if you do not do something to make sure that a fix is only
attempted a finite number of times. The right thing to do is application
specific. The reason for forcing the repeat is very fundamental. A disk
operation, especially a write, which does not complete successfully is
absolutely a catastrophe. Either you fix the condition, or you terminate.
Now you might be asking .. So what good is this? Well, it is available to
handle catastrophic errors such as Disk Full, etc. It should be used to
only handle catastrophic problems which are hard to protect against. Think
of it as a last ditch chance to solve a problem before terminating (which
happened automatically in previous versions). It should never be used for
mundane activities like checking for the existence of a file etc. There is
an explicit routine available which will check for the existence of a file.
If you are creating a file, you should check to ensure that it is a valid
file name prior to calling the creation routine, etc. Your application
should be written such that you do not do an access to a nonexistent index
or data file. These checks are very application specific and should be
handled by you rather than in TBTREE.
The routine, as written, will simply Halt and write an error message if an
error occurs. You will probably want to change it for your application.
Presently, the only legal values for ioErrRec.routineName are as follows:
FILEBUFF unit :
'CloseFile'
'RewriteUntypedFile'
'OpenUntypedFile'
'RewriteTextFile'
'OpenTextFile'
'AppendTextFile'
PAGE unit :
'WriteToDisk'
'ReadFromDisk' *)
procedure UserIOError(ioErrRec : IOErrorRec);
(*!*)
(*\*)
(*///////////////////// I M P L E M E N T A T I O N /////////////////////////*)
implementation
(* This routine will handle disk I/O errors which occur within TBTREE. Since
all disk I/O calls are concentrated either in the FILEBUFF unit or the PAGE
unit, this will trap all disk I/O error calls which occur. Errors are
trapped because I/O checking is turned off in the FILEBUFF unit and in the
PAGE unit. Instead, the Turbo Pascal routine IOResult is called after each
I/O operation. If a value other than 0 is returned, an error has occurred
and this routine is called. When the routine is called, the ioErrorRec
contains the name of the TBTREE routine which contained the error and the
error code returned as a result of the call to IOResult. Using this
information, you can decide what to do. You actually have two options.
First you can cause the program to terminate by either forcing an error or
by using Halt; The program will terminate after running through the exit
routines. If any exit routines do I/O (which they probably do) another
error could occur. If this happens, this routine will be called again. The
second option is to try to handle the error, depending on what it is. How
to correct the error is entirely up to you and your application. Once you
have solved the problem, your routine will terminate and control will
return to the place where the error occurred. The operation which caused
the error routine to be called will be repeated. If you solved the
condition which caused the error, the program will roll merrily along as if
no error ever occurred. If the error occurs again, this routine will be
called again. This will continue until you halt or fix the error
condition. As you can see, this could be the world's best infinite loop
generator if you do not do something to make sure that a fix is only
attempted a finite number of times. The right thing to do is application
specific. The reason for forcing the repeat is very fundamental. A disk
operation, especially a write, which does not complete successfully is
absolutely a catastrophe. Either you fix the condition, or you terminate.
Now you might be asking .. So what good is this? Well, it is available to
handle catastrophic errors such as Disk Full, etc. It should be used to
only handle catastrophic problems which are hard to protect against. Think
of it as a last ditch chance to solve a problem before terminating (which
happened automatically in previous versions). It should never be used for
mundane activities like checking for the existence of a file etc. There is
an explicit routine available which will check for the existence of a file.
If you are creating a file, you should check to ensure that it is a valid
file name prior to calling the creation routine, etc. Your application
should be written such that you do not do an access to a nonexistent index
or data file. These checks are very application specific and should be
handled by you rather than in TBTREE.
The routine, as written, will simply Halt and write an error message if an
error occurs. You will probably want to change it for your application.
Presently, the only legal values for ioErrRec.routineName are as follows:
FILEBUFF unit :
'CloseFile'
'RewriteUntypedFile'
'OpenUntypedFile'
'RewriteTextFile'
'OpenTextFile'
'AppendTextFile'
PAGE unit :
'WriteToDisk'
'ReadFromDisk' *)
procedure UserIOError(ioErrRec : IOErrorRec);
begin
Writeln('Catestrophic I/O error --->> ',ioErrRec.tBTreeIOResult);
Halt;
end;
end. (* end of Error unit *)