WHENEVER instruction
Use the WHENEVER
instruction to define how exceptions must be
handled for the rest of the module.
Syntax
WHENEVER exception-class
exception-action
where exception-class is one of:
{ [ANY] ERROR
| [ANY] SQLERROR
| NOT FOUND
| WARNING
}
and exception-action is one of:
{ CONTINUE
| STOP
| CALL [module.]function
| RAISE
| GOTO label
}
- function can be any function name defined in the program.
- module is the name of a module imported with
IMPORT FGL
. - label must be a label defined in the current program block (main, function or report routine).
Usage
The WHENEVER
instruction defines the exception handling by
associating an exception class with an exception
action.
WHENEVER
instruction is similar
to a C preprocessor macro. It is local to the module and defines the error handling for the rest of
the module, unless a new WHENEVER
instruction is encountered by the compiler, or a
TRY/CATCH
block is used.If no WHENEVER
instruction is used, the default is WHENEVER ERROR
STOP
. Stopping the program in case of error is the recommended default. However, this
default does not catch expression errors like type conversion errors. Consider using the
fglrun.mapAnyErrorToError
FGLPROFILE entry, to catch conversion errors. For more
details, see Default exception handling.
This code example shows a typical WHENEVER
instruction
usage:
WHENEVER ERROR CONTINUE
DROP TABLE mytable -- SQL error will be ignored
CREATE TABLE mytable ( k INT, c VARCHAR(20) )
WHENEVER ERROR STOP
IF SQLCA.SQLCODE != 0 THEN
ERROR "Could not create the table..."
END IF
Exception classes ERROR
and SQLERROR
are synonyms: In the
previous example it is also possible to use WHENEVER SQLERROR
instead of
WHENEVER ERROR
.
Actions
for classes ERROR
, WARNING
and NOT
FOUND
can be set independently:
WHENEVER ERROR STOP
WHENEVER WARNING CONTINUE
WHENEVER NOT FOUND GOTO not_found_handler
...
WHENEVER ... CALL function
instruction, the program flow will go
to the specified function and return to the code block where the exception
occurred:MAIN
DEFINE x INTEGER
WHENEVER ANY ERROR CALL error_handler
-- WHENEVER handler takes effect
LET x = 1/0
DISPLAY "Back in MAIN..."
END MAIN
FUNCTION error_handler()
DISPLAY "error_handler: ", STATUS
END FUNCTION
-- output:
error_handler: -1202
Back in MAIN...
WHENEVER ... CALL
instruction, you do not handle to specify
parentheses after the function name.WHENEVER
instruction, see the
following example:
MAIN
DEFINE x INTEGER
WHENEVER ANY ERROR CONTINUE
-- WHENEVER handler takes effect
LET x = 1/0
DISPLAY "WHENEVER: ", STATUS
-- WHENEVER handler is hidden by TRY/CATCH block
TRY
LET x = 1/0
CATCH
DISPLAY "CATCH : ", STATUS
END TRY
-- WHENEVER handler takes again effect
CALL func()
END MAIN
FUNCTION func()
DEFINE x INTEGER
LET x = 1/0
DISPLAY "WHENEVER: ", STATUS
END FUNCTION
-- Output:
WHENEVER: -1202
CATCH : -1202
WHENEVER: -1202
RAISE
option can be used to propagate exceptions to the caller, which
typically traps the error in a TRY/CATCH
block:-- main.4gl
IMPORT FGL myutils
MAIN
TRY
-- Pass a NULL form name to get error -1110
CALL mutils.open_form(NULL)
CATCH
DISPLAY "Error: ", status
END TRY
END MAIN
-- myutils.4gl
FUNCTION open_form(fn)
DEFINE fn STRING
WHENEVER ERROR RAISE -- Propagate exceptions to caller
OPEN FORM f1 FROM fn
END FUNCTION
WHENEVER [ANY] ERROR RAISE
is not supported
in a REPORT
routine.