Defines a final end block for any ABL block, which
contains code that must run regardless of an error or STOP condition. An end block is an ABL
block that can occur only within another block. The block containing the end block is known
as the associated block. End blocks must occur between the last
line of executable code in the associated block and its END statement.
The purpose of a FINALLY block is to hold clean-up code that must execute regardless of
what else executed in the associated block. It may include code to delete dynamic objects,
write to logs, close outputs, and other routine tasks.
A FINALLY block will run on each iteration of a block, even if that
iteration resulted in an error or STOP condition.
This is the syntax for the FINALLY statement and its related blocks:
Syntax
block-statements
FINALLY :
finally-logic
END [ FINALLY ] .
[ block-end-statement ]
|
-
block-statements
- All of the statements of an enclosing associated ABL block, including
an external procedure block, though a procedure block has no block-end-statement. All ABL blocks other than a simple DO block (one
without TRANSACTION or an ON phrase) can have a FINALLY block.
-
finally-logic
- All statements allowed in a FINALLY block, which can include any valid
ABL statement. For more information on FINALLY block execution, see the Notes for this reference
entry.
-
block-end-statement
- The END statement terminating the enclosing associated block. This
applies to all ABL blocks except for a main external procedure block, which has no
terminating END statement.
Examples
As
shown in r-finally01.p, the FINALLY block executes before
any flow-of-control (LEAVE, NEXT, RETRY, RETURN, or THROW) options
are executed for the associated block. For iterating blocks, the
FINALLY block executes after each iteration of the block.
r-finally01.p
DO ON ERROR UNDO, LEAVE:
/* Since Customer 1000 does not exist, the FIND statement raises ERROR and
execution goes to the FINALLY block before the LEAVE option executes. */
FIND Customer WHERE CustNum = 1000.
MESSAGE "This message never appears because of ERROR condition."
VIEW-AS ALERT-BOX BUTTONS OK.
FINALLY:
MESSAGE "Inside FINALLY block." VIEW-AS ALERT-BOX BUTTONS OK.
/* LEAVE DO block here */
END FINALLY.
END. /* DO */
MESSAGE "Out of DO block." VIEW-AS ALERT-BOX BUTTONS OK.
|
Output:
** Customer record not on file (138)
Inside FINALLY block.
Out of DO block.
|
In r-finally02.p, after
ERROR is raised, execution goes to the CATCH block and then to the
FINALLY block.
r-finally02.p
DO ON ERROR UNDO, LEAVE:
/* Since Customer 1000 does not exist, the FIND statement raises ERROR and
execution goes to CATCH block. */
FIND Customer WHERE CustNum = 1000.
MESSAGE "This message never appears because of ERROR condition."
VIEW-AS ALERT-BOX BUTTONS OK.
CATCH eSysError AS Progress.Lang.SysError:
/* Handler code for SysError condition */
MESSAGE "Inside CATCH block." VIEW-AS ALERT-BOX BUTTONS OK.
/* Execution goes to FINALLY before leaving DO block. */
END CATCH.
FINALLY:
/* Your code */
MESSAGE "Inside FINALLY block." VIEW-AS ALERT-BOX BUTTONS OK.
/* LEAVE DO block here. */
END FINALLY.
END. /* DO */
MESSAGE "Out of DO block." VIEW-AS ALERT-BOX BUTTONS OK.
|
Output:
Inside CATCH block.
Inside FINALLY block.
Out of DO block.
|
Notes
- There can be only one FINALLY block in any associated block. The FINALLY
statement must come after all other executable statements in the associated block and
before the END statement. If the associated block contains CATCH statements, the FINALLY
block must come after all CATCH blocks. Note that the FINALLY statement can be used in a block with no CATCH blocks.
- The FINALLY block will not execute if a QUIT statement is in effect and it is not
handled.
- Since it executes after an invoked CATCH block, the FINALLY
block can also be used to perform common post-CATCH clean up tasks,
rather than repeating common code in all the CATCH blocks present
in the associated block.
- The transaction of the associated block is either complete (success)
or undone (failure) when FINALLY executes. Therefore, any UNDO statement
within the FINALLY block will only undo the work in the FINALLY block.
- The FINALLY block is an undoable block with implicit ON ERROR UNDO,
THROW error handling, and like all blocks, FINALLY blocks implicitly throw all stop
objects. You cannot explicitly override the ON ERROR directive for a FINALLY block. If a
statement within the FINALLY block raises an error or STOP condition, by default, the
FINALLY block will be undone, and the condition will be raised in the block that encloses
the associated block of the FINALLY block. Error is not raised in the associated block.
Otherwise, infinite looping could occur. To avoid having the error thrown out, you can use
a CATCH block to handle the error as in other blocks.
- If the AVM detects an unhandled QUIT condition in the associated block,
the FINALLY block does not run and the AVM processes the condition. If the associated
block has an ON QUIT phrase, the QUIT condition is handled and cleared by the time the AVM
is ready to execute the FINALLY block, and the FINALLY block executes. See the ON QUIT
phrase reference entry for a description of QUIT condition behavior and handling.
- For more information on FINALLY blocks see OpenEdge Development: ABL Error Handling.