TRY / CATCH	(local error handling)

In the latest Version of GFA-BASIC for MS-DOS (4.50) and GFA-BASIC for Windows (4.20) a new pair of Commands replaces the old ON ERROR GOSUB and RESUME commands.

The old method worked globally, that is it was not usable for a structured program: a catch all error routine was very hard to write and to maintain.

TRY and CATCH appears always as a pair inside a procedure or function. The statements after TRY are executed as usual, and the CATCH acts as the standart RETURN (or ENDFUNC). But if an error occurs, execution is transfered to the CATCH.

Example:
test
PROCEDURE test
	LOCAL i
	TRY
		FOR i = -9 TO 9
			PRINT @Rezip(i);", ";
		NEXT i
	CATCH
	PRINT "There is an error occured in PROCEDURE test"
	PRINT ERR$(ERR)
	KEYGET a%
RETURN
FUNCTION Rezip(x)
	RETURN 1/x
ENDFUNC

The above program will print -0.11.., -0.125, -0.14.., -0.16..,-0.2,-0.25,-0.33..,-0.5,-1,
and then it will print the message and the error text, wait for a keystroke and return.

A simple change in the function, using TRY/CATCH again, permits to supply a error value (1/0 is not defined, but one divided by very small numbers gives a very high result, now lets supply one,catching overflows as well).

FUNCTION Rezip(x)
TRY
	RETURN 1/x
CATCH
RETURN 1E99
ENDFUNC

This changed program will continue after -1 with 1E+99,1,0.5,0.3.. ...

And because the TRY/CATCH does work locally, other errors in test would be handled there.

A second example is a procedure reading a configuration value from a file

@ReadValue("CONFIG.CFG",1000,Anzahl&)
PROCEDURE ReadValue(File$,Def&, VAR Ret&)
	TRY 
		OPEN "I",#1,File$
		INPUT #1,Ret&
		CLOSE #1
	CATCH
	CLOSE #1		//in case file opened ok, but input failed
	Ret& = Def&	// Return default value
RETURN

A third example, just displaying a graph of the function sin(x)/x.  This function is everywhere defined and gives nice results, except for zero, giving no result at all there. Very small numbers, positive and negative, approach 1.0, so lets put this value there (sin(0.0)/0.0 = 0.0/0.0 could give 1.0?).

SCREEN 18						//Screen for DOS
OPENW #1,0,0,_X,_Y,0		//Window for Windows
y0&=_Y/2,ys&=_Y/2
COLOR 8
FOR  i&=0 TO _X STEP 2
	ix = (i&-_X/2)/20
	PLOT i&,y0& - @sinx-by-x(ix) * ys&
NEXT i&
KEYGET a%
FUNCTION sinx_by_x(x)
	TRY
		RETURN SIN(x)/x
	CATCH
	RETURN 1
ENDFUNC

This modified program does display a simple three d view.
SCREEN 18						//Screen for DOS
OPENW #1,0,0,_X,_Y,0		//Window for Windows
y0&=_Y/2,ys&=_Y/2
COLOR 0
FOR j&=0 TO _Y STEP 4
	jx = (j&-_Y/2)/20,	jx2 = jx*jx
	FOR i&=0 TO _X STEP 2
		ix = (i&-_X/2)/20, f = SQR(ix^2 + jx2)
		z& = y0& - @sinx_by_x(f)*ys&
		PSET i&,z&,15
		LINE i&,z&+1,i&,_Y
	NEXT i&
	y0&++
NEXT j&
KEYGET a%
FUNCTION sinx_by_x(x)
	TRY
		RETURN SIN(x)/x
	CATCH
	RETURN 1
ENDFUNC

Another benefit from using TRY/CATCH instead of the old ON ERROR - RESUME is for the compiler. With RESUME it would need to do a TRY-CATCH around every single statement in the program or many compileroptions spread everywhere in the program (roughly equivalent to TRY-CATCH, but with quite a bit more problems), thus requiring extensive work on the program after it's running in the interpreter to make it compileable without using up much of it's speed and increasing it's space requierement just for an eventual error.

