Local error handling
Try
// code
Catch
// error handler
EndCatch
Try and Catch/EndCatch appears always as a pair inside a procedure or function. The statements after Try are executed as usual, and the part between Catch/EndCatch an error occurs, otherwise execution is transferred to the first statement after EndCatch.
Try/Catch/EndCatch constructions cannot be nested; otherwise there can be more than one error handler per subroutine. This differs from the GFA-BASIC 16 where the Catch functions as a return from subroutine.
test
Me.Close
Procedure test
Local i, a%
Try
For i = -9 To 9
Print @Rezip(i); ", ";
Next i
Catch
Print "There is an error occured in Procedure test"
Print Err$(Err)
Print "Press any key to continue"
KeyGet a%
EndCatch
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 an 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
EndCatch
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
Local size% = 10
ReadValue("CONFIG.CFG", 1000, size%)
Print size%
Procedure ReadValue(File$, Def%, ByRef Ret%)
Try
Open File$ for Input As # 1
Input # 1, Ret%
Close # 1
Catch
Ret% = Def% // Return default value
EndCatch
Close # 1
Return
A third example, just displaying a graph of the function Sin(x)/x. This function is defined and gives good results, except for zero, giving no result at all. Very small numbers, positive and negative, approach 1.0, so let's put this value there (Sin(0.0)/0.0 = 0.0/0.0 could give 1.0?).
Local Int a, i, y0, ys
Local ix As Double
OpenW # 1, 0, 0, _X, _Y, 0
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
CloseW 1
Function sinx_by_x(x)
Try
sinx_by_x = Sin(x) / x
Catch
sinx_by_x = 1
EndCatch
EndFunc
This modified program does display a simple three dimensional view.
Local Int a, i, j, y0, ys
Local Double ix, jx, jx2, f, z
OpenW # 1, 0, 0, _X, _Y, 0
y0 = _Y / 2, ys = _Y / 2
Color RGB(255, 0, 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, RGB(192, 192, 192)
Line i, z + 1, i, _Y
Next i
y0++
Next j
KeyGet a
CloseW 1
Function sinx_by_x(x)
Try
sinx_by_x = Sin(x) / x
Catch
sinx_by_x = 1
EndCatch
EndFunc
See On Error for more information on error trapping.
Problems can arise when using Ocx objects when an error occurs in a procedure with no Try/Catch construction which is called from another procedure with one, as shown in the example below:
Ocx Command cmd = "Hello", 10, 10, 100, 22
Try
SubRoutine
Catch
Message Err$
EndCatch
Do : Sleep : Until Me Is Nothing
Procedure SubRoutine
Local n As Int32
n = 2 / 0
EndProcedure
Sub cmd_Click
Message "Hello"
EndSub
An error is called when the the 'Divide by Zero' error is encountered as it is captured by the main Try/Catch construct; however, the Ocx Command button is now inoperative, as would be any other Ocx objects, eventhough the program is still technically running.
To overcome this problem, simply insert a Try/Catch construct inside the called procedure as well. As can be seen if you run the amended version of the previous example below, following the error message, the Ocx Command Button is still functional and the program will continue running as designed.
Ocx Command cmd = "Hello", 10, 10, 100, 22
Try
SubRoutine
Catch
Message Err$
EndCatch
Do : Sleep : Until Me Is Nothing
Procedure SubRoutine
Local n As Int32
Try
n = 2 / 0
Catch
Message Err$
EndCatch
EndProcedure
Sub cmd_Click
Message "Hello"
EndSub
{Created by Sjouke Hamstra; Last updated: 31/08/2015 by James Gaite}