Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Class-based Exception - CLEANUP block always skipped.

Former Member
0 Kudos

Using NetWeaver 7.0, I am not able to actually make my program enter a CLEANUP block inside the try...endtry statements. The error is caught, the text is gotten, but in DEBUG I stop at CLEANUP, then at ENDTRY. The statements in CLEANUP are ignored.

To verify this I copied a program from SAP's documentation and it does precisely what mine does. I don't find SAP Notes on

this subject. Any insight about why this happens would be appreciated..

The code below is copied and simplified from on-line documentation and it fails to enter CLEANUP when executed with number = 0. Please note also that if the code is converted to a perform a subroutine with a try...endtry...from within another try...endtry...everything works except the CLEANUP block.

REPORT demo_handle_exceptions.
PARAMETERS number TYPE i.

DATA quotient TYPE p DECIMALS 2.
DATA oref TYPE REF TO cx_root.
DATA text TYPE string.

START-OF-SELECTION.
  WRITE: / 'Testing division with', number.
  ULINE.
  TRY.
      quotient =  1 / number.  "in debug, change to 0.10 here
    CATCH cx_sy_zerodivide INTO oref.
      text = oref->get_text( ).
    CLEANUP.
      CLEAR quotient.
  ENDTRY.

  IF NOT text IS INITIAL.
    WRITE / text.
  ENDIF.
  WRITE: / 'Final result:', quotient. 

Output

Testing division with 0

Division by zero

Final result: 0.10

1 ACCEPTED SOLUTION

Former Member
0 Kudos

My understanding is that the CLEANUP block would only be called if there is no handler to process the exception that actually occurs. You can test this by commenting out the CATCH statement.

Rob

OK - I tried it with your code and it dumped. But then I tried it with the code from the example in the help file and the CLEANUP is executed:

PARAMETERS number TYPE i.
DATA: result TYPE p LENGTH 8 DECIMALS 2,
      oref   TYPE REF TO cx_root,
      text   TYPE string.

TRY.
    IF ABS( number ) > 100.
      RAISE EXCEPTION TYPE cx_demo_abs_too_large.
    ENDIF.
    PERFORM calculation USING    number
                      CHANGING result
                               text.
  CATCH cx_sy_arithmetic_error INTO oref.
    text = oref->get_text( ).
  CATCH cx_root INTO oref.
    text = oref->get_text( ).
ENDTRY.

IF NOT text IS INITIAL.
  WRITE / text.
ENDIF.

WRITE: / 'Final result:', result.

*&---------------------------------------------------------------------*
*&      Form  calculation
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM calculation USING    p_number LIKE number
                 CHANGING p_result LIKE result
                          p_text   LIKE text
                          RAISING  cx_sy_arithmetic_error.

  DATA l_oref TYPE REF TO cx_root.

  TRY.
      p_result =  1 / p_number.
      WRITE: / 'Result of division:', p_result.
      p_result = SQRT( p_number ).
      WRITE: / 'Result of square root:', p_result.
*    CATCH cx_sy_zerodivide INTO l_oref.       "  Remove
*      p_text = l_oref->get_text( ).           "  Remove
    CLEANUP.
      result = 999.                             " change to a big number
  ENDTRY.

ENDFORM.                    "calculation

Edited by: Rob Burbank on Mar 16, 2010 3:12 PM

4 REPLIES 4

Former Member
0 Kudos

My understanding is that the CLEANUP block would only be called if there is no handler to process the exception that actually occurs. You can test this by commenting out the CATCH statement.

Rob

OK - I tried it with your code and it dumped. But then I tried it with the code from the example in the help file and the CLEANUP is executed:

PARAMETERS number TYPE i.
DATA: result TYPE p LENGTH 8 DECIMALS 2,
      oref   TYPE REF TO cx_root,
      text   TYPE string.

TRY.
    IF ABS( number ) > 100.
      RAISE EXCEPTION TYPE cx_demo_abs_too_large.
    ENDIF.
    PERFORM calculation USING    number
                      CHANGING result
                               text.
  CATCH cx_sy_arithmetic_error INTO oref.
    text = oref->get_text( ).
  CATCH cx_root INTO oref.
    text = oref->get_text( ).
ENDTRY.

IF NOT text IS INITIAL.
  WRITE / text.
ENDIF.

WRITE: / 'Final result:', result.

*&---------------------------------------------------------------------*
*&      Form  calculation
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM calculation USING    p_number LIKE number
                 CHANGING p_result LIKE result
                          p_text   LIKE text
                          RAISING  cx_sy_arithmetic_error.

  DATA l_oref TYPE REF TO cx_root.

  TRY.
      p_result =  1 / p_number.
      WRITE: / 'Result of division:', p_result.
      p_result = SQRT( p_number ).
      WRITE: / 'Result of square root:', p_result.
*    CATCH cx_sy_zerodivide INTO l_oref.       "  Remove
*      p_text = l_oref->get_text( ).           "  Remove
    CLEANUP.
      result = 999.                             " change to a big number
  ENDTRY.

ENDFORM.                    "calculation

Edited by: Rob Burbank on Mar 16, 2010 3:12 PM

0 Kudos

Thanks, Rob. Your fix works and the example at:

[http://help.sap.com/saphelp_nw04/Helpdata/EN/a9/b8eef8fe9411d4b2ee0050dadfb92b/content.htm]

is just flat out wrong, unfortunately!

However, the "Official ABAP Programming Guide" published just last fall shows the cleanup in the same try...endtry also. But I abend when I try something approximating that example, possibly because of versions of NetWeaver.

Just for the record, what NetWeaver version did you try this on?

0 Kudos

I commented out the same lines in the link you gave and it behaved the same as in my example, so I think it works OK.

Rob

Sandra_Rossi
Active Contributor
0 Kudos

that's explained here in the ABAP documentation, chapter "System Behavior After Class-Based Exception":

> If a handler is found, the CLEANUP blocks of all TRY control structures that have thus far been scanned unsuccessfully are executed from the inside to the outside.

The following will display Final result: 998 if you enter number = 0


PARAMETERS number TYPE i.

DATA quotient TYPE p DECIMALS 2.
DATA oref TYPE REF TO cx_root.
DATA text TYPE string.

START-OF-SELECTION.
  WRITE: / 'Testing division with', number.
  ULINE.
  TRY.
      TRY.
          TRY.
              quotient =  1 / number.
            CLEANUP.
              quotient = 999.
          ENDTRY.
        CLEANUP.
          SUBTRACT 1 FROM quotient.
      ENDTRY.
    CATCH cx_sy_zerodivide INTO oref.
      text = oref->get_text( ).
  ENDTRY.

  IF NOT text IS INITIAL.
    WRITE / text.
  ENDIF.
  WRITE: / 'Final result:', quotient.