=====Structured Exception Handling=====
//by Richard Russell, April 2008//\\ \\ Several modern programming languages (e.g. **C++**, **Java** and **Visual Basic**) provide a [[http://en.wikipedia.org/wiki/Exception_handling|Structured Exception Handling]] capability. Typically this uses a syntax similar to the following:\\ \\
try
{
// Code you want to execute, which might result in an error
}
catch
{
// Code to execute if an error occurred in the 'try' clause
}
The **try** clause contains the code you want to execute, which may consist of any number of statements and may optionally call subroutines. This is the code that you anticipate //might// result in an error being generated. The **catch** clause contains the code you want to be executed if an error occurs whilst executing the **try** clause. Whether or not an error occurs, execution continues normally after the **catch** clause.\\ \\ BBC BASIC does not natively provide such a facility, but in //BBC BASIC for Windows// and //BBC BASIC for SDL 2.0// you can emulate the behaviour quite easily as follows:\\ \\
ON ERROR LOCAL IF FALSE THEN
REM. 'Try' clause:
REM. Code you want to execute, which might result in an error
ELSE
REM. 'Catch' clause:
REM. Code to execute if an error occurred in the 'try' clause
ENDIF : RESTORE ERROR
Note particularly the unusual compound statement **"ON ERROR LOCAL IF FALSE THEN"** and the **"RESTORE ERROR"** on the last line.\\ \\ If you want to deal with different errors in different ways you can easily do that as follows:\\ \\
ON ERROR LOCAL IF FALSE THEN
REM. 'Try' clause:
INPUT expr$
PRINT EVAL(expr$)
ELSE
REM. 'Catch' clause:
CASE ERR OF
WHEN 18: PRINT "Division by zero exception"
WHEN 20: PRINT "Number too big exception"
OTHERWISE RESTORE ERROR : ERROR ERR, REPORT$
ENDCASE
ENDIF : RESTORE ERROR
In this example the user can enter an expression, which is evaluated by BASIC and the result printed. If an expected error occurs during the evaluation of the expression (for example if the user entered **1/0**) then a message appropriate to the error is printed. If an unexpected error occurs it is 'passed down' to the exception handler at the next lower level (if any).\\ \\ Languages that provide Structured Exception Handling generally also provide a mechanism for causing a specific error to occur, typically by means of a **throw** statement:\\ \\
{
throw new StrangeException("Oh dear");
}
In BBC BASIC you can of course emulate this directly:\\ \\
ON ERROR LOCAL IF FALSE THEN
REM. 'Try' clause:
INPUT expr$
IF expr$="" ERROR 100, "Empty string entered" : REM 'Throw'
PRINT EVAL(expr$)
ELSE
REM. 'Catch' clause:
CASE ERR OF
WHEN 18: PRINT "Division by zero exception"
WHEN 20: PRINT "Number too big exception"
WHEN 100: PRINT "Nothing was entered"
OTHERWISE RESTORE ERROR : ERROR ERR, REPORT$
ENDCASE
ENDIF : RESTORE ERROR
Here an error is generated if the user enters nothing, and this is handled by the **catch** clause.\\ \\ If the code contained in the **try** clause includes a function or procedure call, and if an error occurs in that function or procedure (or any that it calls), then any **formal parameters** and **LOCAL** variables will //not be automatically restored// to the values they had before the call. If this is a problem **RESTORE LOCAL** can be used within the function or procedure (see [[/Cascaded%20error%20handling|Cascaded error handling]]):\\ \\
DEF PROCmightfail(parameters)
LOCAL list_of_locals
PRIVATE list_of_privates
ON ERROR LOCAL RESTORE LOCAL:ERROR ERR,REPORT$
REM. Code which might result in an error
ENDPROC