The error correction code should be simple and carefully designed. If an error happens while executing the error correction code the interpreter will terminate the program code or at least will go up to the next level of exception handling.
When the interpreter executes a jump to the error correction code caused by an error the ON ERROR GOTO functionality is switched off automatically until a new ON ERROR GOTO instruction is executed. This is done to prevent infinite looping caused by errors in the error correction code. The error correction code therefore usually executes an ON ERROR GOTO statement pointing to the start of the error correction code itself immediately before the execution the statement RESUME.
At the same time an error correction code can not have its own error correction code. If an error correction code uses the ON ERROR GOTO statement to specify its own error correction code it looses the resume point when an error occurs. In other words the remembered point of code where to resume after error correction is always the statement where the last error occurred. There is only a single resume point during execution and there is no stack of resume points.
The error handling statements use labels. Labels in ScriptBasic are local. You can not refer to a label in a function or subroutine from outside and vice versa. There is no need to do so with the error handling functions as well. The issue is that the jumping instruction is executed some time after the label was used.
What happens when an statement ON ERROR GOTO is used in function X and the error happens in function Y called from function X. Will the code jump from one function to the other?
sub Y
error 1
end sub
call X
end
sub X
on error goto ErrorLabel
print "starting sub Y\n"
call Y
print "sub Y returned\n"
exit sub
ErrorLabel:
print "an error occurred while executing Y\n"
end sub
will print
starting sub Y
an error occurred while executing Y
The answer seems to be yes, but the case is not so simple. When the error occurs the interpreter sees that there is no ON ERROR GOTO statement currently in effect in the subroutine Y. Therefore it handles the error and terminates the execution of the subroutine Y. The subroutine returns and the error is inherited to the statement CALL invoking Y. The interpreter gets into the error condition again and now, at this level of execution there is an effective ON ERROR GOTO statement, which is executed.
To see that this really happens this way see the following example:
sub Y
print "Y started\n"
if Flag = 1 Then
error 1
end if
print "Y finishes\n"
end sub
Flag = 1
call X
end
sub X
on error goto ErrorLabel
print "starting sub Y\n"
call Y
print "sub Y returned\n"
exit sub
ErrorLabel:
print "an error occurred while executing Y\n"
Flag = 0
Resume
end sub
will print
starting sub Y
Y started
an error occurred while executing Y
Y started
Y finishes
sub Y returned
In this code the subroutine Y causes error if the global variable Flag is 1. The error correction code sets this variable to zero and corrects the error with this action. After resuming the execution the code continues at the subroutine call and not at the error statement. This shows that the error condition does not jump out of the function. It rather terminates the function and propagates the error code up to the caller until the main program level is reached and program execution is terminated or there is an effective ON ERROR GOTO or ON ERROR RESUME statement.
When an ON ERROR GOTO/RESUME statement is executed it overrides the settings of the previously executed ON ERROR GOTO/RESUME statement, which is in effect. But it does not override the settings of any higher level settings, because those are not currently in effect and the settings are restored when the program returns from the actual function or subroutine. For example:
handled by the subroutine.\n"
error 2
FinishLabel:
end sub
on error goto ErrorLabel
call ErrorSub
print "No error"
goto FinishLabel
ErrorLabel:
print "Error code: ",error(),nl
FinishLabel:
end
Global const nl ="\n"
sub ErrorSub
on error goto ErrorLabel
error 1
print "No error has occurred in the function. Weird.\n"
goto FinishLabel
ErrorLabel:
print "An error has occurred inside the sub\n"
print "and now generating another error, which is not
will print
and now generating another error, which is not
handled by the subroutine.
Error code: 2
An error has occurred inside the sub
Note that the ON ERROR GOTO setting of the module outside the subroutine remained valid although another ON ERROR GOTO setting was issued inside the subroutine.