ON ERROR
(Redirected from LASTHANDLER)
Jump to navigation
Jump to search
The ON ERROR statement is used in conjunction with GOTO to handle errors in a program.
Syntax
- Legacy QuickBASIC/QBasic
- ON ERROR GOTO {lineNumberOrLabel | 0}
- QB64-PE extension
- ON ERROR GOTO {_LASTHANDLER | _NEWHANDLER lineNumberOrLabel}
Parameters
- lineNumberOrLabel must be a line number or program label in the main part of your program usually placed after the END or SYSTEM statement. Line numbers or labels inside of SUB or FUNCTION blocks are not allowed.
- 0 (zero) will disable all program based error handling, i.e. errors remain unhandled.
Description
- An unhandled error in a program will cause execution to stop and an error message box is displayed to the user, who can choose to continue (ignore the error - which could have unexpected results) or end the program.
- Use ON ERROR when your program performs operations that are likely to generate errors, like file access operations.
- ON ERROR statements can be in the main code section or in SUB or FUNCTION procedures, but the line number or label must always be in the main code section.
- ON ERROR statements take precedence in the order they are encountered, i.e. the most recently set handler is used. Subsequent ON ERROR statements will override the previous one.
- ON ERROR GOTO 0 can be used to disable program based error trapping and give default error message boxes.
- GOTO is required in the statement. Cannot use GOSUB.
- QB64 and QB64-PE do not support the PDS (QuickBASIC 7) ON ERROR RESUME NEXT statement.
- Since QB64-PE v3.14.1 the _NEWHANDLER and _LASTHANDLER keywords can be used to build up a history chain of the used error handlers. This is especially useful inside SUB or FUNCTION code provided in external libraries, when the handlers are unknown (see Example 3).
- Works also over several nested or recursive sub-/function calls, but care must be taken for correct exit conditions to avoid crashes due to extensive memory usage. Each use of _NEWHANDLER should have a matching use of _LASTHANDLER.
- Organize your code so that _NEWHANDLER is not executed 1000s of times in a tight loop, best use is at the entry point of a SUB or FUNCTION. Place _LASTHANDLER at the end point, but make sure it's also called when using EXIT SUB or EXIT FUNCTION.
- Memory crashes may only happen on unbalanced use of _NEW-/_LASTHANDLER, if you have much more (several 10000s) _NEWHANDLER than _LASTHANDLER executions, so if you take the care and follow given recommendations, then everything will just work fine.
- The use of _LASTHANDLER is always save. If the history chain has no more enries, then it is synonymous to the 0 (zero) parameter of the legacy syntax, i.e. disabling program based error trapping.
- The use of the legacy ON ERROR GOTO 0 will also completly reset/clear the handler history chain.
Availability
- The _NEWHANDLER and _LASTHANDLER functionality is introduced in QB64-PE v3.14.1.
Examples
- Example 1
- Using an error handler that prints the error and then continues with the next program line.
'install our own error handler ON ERROR GOTO errHandler 'now simulate an "Out of Memory" error ERROR 7 'our error handler will return to this point PRINT "Error was handled.": PRINT 'now we disable our error handler ON ERROR GOTO 0 COLOR 9: PRINT "Handler disabled.": COLOR 7 'without our own error handler the following error is reported 'in the usual message box popup again PRINT "The next error will no longer be handled, press any key ...": SLEEP ERROR 7 END 'the error handler label must be part of the main program, local 'labels inside a SUB/FUNCTION are not allowed for error handlers errHandler: COLOR 10: PRINT "Start handling error"; ERR; "on program file line"; _ERRORLINE; BEEP: PRINT "... done.": COLOR 7 RESUME NEXT 'returns execution to the code following the error |
Start handling error 7 on program file line 6 ... done. Error was handled. Handler disabled. The next error will no longer be handled, press any key ... |
- Example 2
- Using an alternative error handler in a SUB procedure.
ON ERROR GOTO mainHandler ERROR 7 PRINT "Error was handled.": PRINT LegacyErrorTest PRINT "Error was handled.": PRINT ERROR 7 PRINT "Error was handled.": PRINT ON ERROR GOTO 0 COLOR 9: PRINT "Handler disabled.": COLOR 7 PRINT "The next error will no longer be handled, press any key ...": SLEEP ERROR 7 END 'the error handler label must be part of the main program, local 'labels inside a SUB/FUNCTION are not allowed for error handlers mainHandler: COLOR 10: PRINT "Main handler starts handling error"; ERR; "on program file line"; _ERRORLINE; BEEP: PRINT "... done.": COLOR 7 RESUME NEXT 'an alternative error handler which we set from within a SUB/FUNCTION 'however, the error handler label must still be part of the main program subHandler: COLOR 12: PRINT "Sub handler starts handling error"; ERR; "on program file line"; _ERRORLINE; BEEP: PRINT "... done.": COLOR 7 RESUME NEXT SUB LegacyErrorTest 'the next line overrides the currently active "mainHandler" 'with our new "subHandler" ON ERROR GOTO subHandler ERROR 7 'unfortunately the legacy QuickBASIC/QBasic syntax has no function to 'restore back to the old handler, so you need to know which handler was 'active and restore that manually ON ERROR GOTO mainHandler END SUB |
Main handler starts handling error 7 on program file line 4 ... done. Error was handled. Sub handler starts handling error 7 on program file line 33 ... done. Error was handled. Main handler starts handling error 7 on program file line 8 ... done. Error was handled. Handler disabled. The next error will no longer be handled, press any key ... |
- Example 3
- Same as example 2, but using QB64-PE specific extensions _NEWHANDLER and _LASTHANDLER.
ON ERROR GOTO mainHandler ERROR 7 PRINT "Error was handled.": PRINT QB64peErrorTest PRINT "Error was handled.": PRINT ERROR 7 PRINT "Error was handled.": PRINT ON ERROR GOTO 0 COLOR 9: PRINT "Handler disabled.": COLOR 7 PRINT "The next error will no longer be handled, press any key ...": SLEEP ERROR 7 END mainHandler: COLOR 10: PRINT "Main handler starts handling error"; ERR; "on program file line"; _ERRORLINE; BEEP: PRINT "... done.": COLOR 7 RESUME NEXT subHandler: COLOR 12: PRINT "Sub handler starts handling error"; ERR; "on program file line"; _ERRORLINE; BEEP: PRINT "... done.": COLOR 7 RESUME NEXT SUB QB64peErrorTest 'the next line overrides the currently active "mainHandler" 'with our new "subHandler", but the _NEWHANDLER keyword explicitly 'designates this as override and to remember the former handler ON ERROR GOTO _NEWHANDLER subHandler ERROR 7 'now the following _LASTHANDLER syntax can easily restore back 'to the former handler without we need to know which one it was, ON ERROR GOTO _LASTHANDLER END SUB |
Main handler starts handling error 7 on program file line 4 ... done. Error was handled. Sub handler starts handling error 7 on program file line 30 ... done. Error was handled. Main handler starts handling error 7 on program file line 8 ... done. Error was handled. Handler disabled. The next error will no longer be handled, press any key ... |
See also