home *** CD-ROM | disk | FTP | other *** search
- (* 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 *)