15.5. The Error Unit

Our next set of routines are those that handle errors. To refresh your memory, we take the approach, pioneered by Borland in Turbo Pascal, of halting on the first error. Not only does this greatly simplify our code, by completely avoiding the sticky issue of error recovery, but it also makes much more sense, in my opinion, in an interactive environment. I know this may be an extreme position, but I consider the practice of reporting all errors in a program to be an anachronism, a holdover from the days of batch processing. It's time to scuttle the practice. So there.

In our original Cradle, we had two error-handling procedures: Error, which didn't halt, and Abort, which did. But I don't think we ever found a use for the procedure that didn't halt, so in the new, lean and mean unit Errors, shown next, procedure Error takes the place of Abort.

unit Errors;

interface
procedure Error(s: string);
procedure Expected(s: string);

implementation

{ Write error Message and Halt }
procedure Error(s: string);
begin
        WriteLn;
        WriteLn(^G, 'Error: ', s, '.');
        Halt;
end;

{ Write "<something> Expected" }
procedure Expected(s: string);
begin
        Error(s + ' Expected');
end;

end.

As usual, here's a test program:

program Test;
uses WinCRT, Input, Output, Errors;

begin
        Expected('Integer');
end.

Have you noticed that the “uses” line in our main program keeps getting longer? That's OK. In the final version, the main program will only call procedures in our parser, so its use clause will only have a couple of entries. But for now, it's probably best to include all the units so we can test procedures in them.