CLEANUP

Basic form

CLEANUP.

Effect

Defines the CLEANUP area introduced by a TRY block. Each TRY block can have a maximum of one CLEANUP clause. If this clause is used at all, it must be included after the last CATCH and before the last ENDTRY. The CLEANUP area includes all the statements between CLEANUP and ENDTRY.

At runtime, if the system cannot find a handler for an exception within the TRY block, but that exception is caught further up the call hierarchy, all the routines lying between the exception and the handler are ended. In principle, this can lead to a program being in an inconsistent state, or external resources not being released. In many cases, the handler - particularly if the system has jumped several levels up the call hierarchy - cannot react to the situation adequately.

In such cases, the CLEANUP area is used to restore the program to a consistent state. If an exception is not caught in the current TRY block, but at a higher level, the system first executes the CLEANUP area of the TRY block before leaving the context, and then passes the exception up the call hierarchy. This may lead to a situation, whereby other CLEANUP areas from surrounding TRY blocks are executed, until the exception finally arrives at the appropriate handler.

Since the way that the exception must follow (from the trigger point to the handler) is pre-defined, you cannot change it by means of statements in the CLEANUP area. For this reason, you cannot use any statement that changes the flow of control, and which would cause the system to leave the CLEANUP area prematurely - such as RETURN, STOP, and REJECT, but also EXIT, CONTINUE and CHECK, if executing would involve leaving the CLEANUP area. If another exception occurred within the CLEANUP area, this would also affect the program's control flow. For this reason, all exceptions that occur locally within a CLEANUP area must be handled locally. Otherwise a runtime error occurs. The following example is procided to clarify these points:

Example

The goods receipt class of a firm (the CL_GOODS_RECEPTION class) contains a method enter, which posts goods receipt. The system posts the goods by adding the number of items delivered to the stock level, stock, and then deducting the price of the goods from the account account.

CLASS CL_GOODS_RECEPTION IMPLEMENTATION.
...
  METHOD enter.
    CALL METHOD stock->increase EXPORTING amount = number_of_items.
    TRY.
      price = number_of_items * price_per_item.
      CALL METHOD account->withdraw EXPORTING amount = price.
    CLEANUP.
        CALL METHOD stock->decrease EXPORTING amount = number_of_items.
  ENDTRY.
  ENDMETHOD.
...
ENDCLASS.

If an exception occurs while the price is being deducted from the account - for example, if there is insufficient money in the account to cover the price of goods (CX_NO_COVERING) - this exception is not handled at that point. However, the stock level must be re-adjusted to maintain consistency. The goods receipt class could look like this:

DATA goods_reception TYPE REF TO CL_GOODS_RECEPTION.
...
TRY.
  ...
  CALL METHOD goods_reception->enter EXPORTING number_of_items = ...
  ...
CATCH CX_STOCK_FULL CX_NO_COVERING.
  CALL METHOD send_goods_back.
ENDTRY.

Related

TRY, CATCH, RAISE EXCEPTION