Why NOT to have a wrapper around Exception (RAISE) ?

By | November 2, 2016 | Exceptions | 14,372 | 5

Class based exception are more powerful compared to the “legacy” exceptions. But you don’t want to create wrapper around the Exceptions?

Preface

In the blog The Harlem Function Module Shuffle on (old (older SDN)) SCN, Paul Hardy showed a good way to wrap the FM calls to be able leverage them in chained method calls and use the class-based exceptions.

His pattern has a method throw_exception_on_error_from which, in particular, I try to avoid. You would ask why?

Lost Benefit by Wrapper

Almost all of Std SAP FMs, BAPIs etc has the similar kind of structure: Use a wrapper subroutine to raise the exception with (or without) message, call this subroutine to all the different places.
So, whenever there is an short-dump, developer would have a hard time to find from where the exception is raised.

In ABAP debugger, we have a button “Display Trigger Location” whenever an exception is raised. As name suggests the button shows the exact location of the RAISE statement.

sap_abap_debugger_display_trigger_location_0

If the wrapper is used, the button “Display Trigger Location” shows the location of the RAISE within the wrapper method. But the button doesn’t show the call stack at all hence benefit is lost.

In Action

Checkout this program. Very simple demo of raising the exception from the deep withing the functional methods (SELECT_*) and using the wrapper error methods (ERROR_*) to raise the exception.

 
CLASS lcl_data DEFINITION.
  PUBLIC SECTION.
    METHODS:
      get_data
        RAISING zcx_gen_exception.
  PRIVATE SECTION.
    METHODS:
      select_1  RAISING zcx_gen_exception,
      select_2  RAISING zcx_gen_exception,
      select_3  RAISING zcx_gen_exception,
      select_4  RAISING zcx_gen_exception,
      select_5  RAISING zcx_gen_exception,
      select_6  RAISING zcx_gen_exception.
    METHODS:
      error_a   RAISING zcx_gen_exception,
      error_b   RAISING zcx_gen_exception,
      error_c   RAISING zcx_gen_exception.
ENDCLASS.
 
START-OF-SELECTION.
  TRY .
      DATA(lo_data) = NEW lcl_data( ).
      lo_data->get_data( ).
    CATCH zcx_gen_exception INTO DATA(lo_exc).
      "--- use "Display Trigger Location"
  ENDTRY.
 
 
CLASS lcl_data IMPLEMENTATION.
  METHOD get_data.
    BREAK-POINT.
    "F7 from here
    select_1( ).
  ENDMETHOD.
  METHOD select_1.
    select_2( ).
  ENDMETHOD.
  METHOD select_2.
    select_3( ).
  ENDMETHOD.
  METHOD select_3.
    select_4( ).
  ENDMETHOD.
  METHOD select_4.
    select_5( ).
  ENDMETHOD.
  METHOD select_5.
    select_6( ).
  ENDMETHOD.
  METHOD select_6.
    "raise EXCEPTION type ZCX_GEN_EXCEPTION.
    error_a( ).
  ENDMETHOD.
  METHOD error_a.
    error_b( ).  "wrapper
  ENDMETHOD.
  METHOD error_b.
    "do something and pass the Text ID to _c
    error_c( ).
  ENDMETHOD.
  METHOD error_c.
    RAISE EXCEPTION TYPE zcx_gen_exception.
  ENDMETHOD.
ENDCLASS.
 
 

In the debugger,

sap_abap_debugger_display_trigger_location

when check the trigger location

sap_abap_debugger_trigger_location

Now, change few things to raise the exception directly from the method SELECT_6( ), use method ERROR_A( ) as prerequisite builder and remove the RAISE statement from the method ERROR_C( ).

 
  METHOD select_6.
    error_a( ).
    raise EXCEPTION type ZCX_GEN_EXCEPTION.
  ENDMETHOD.
  METHOD error_a.
    error_b( ).  "wrapper
  ENDMETHOD.
  METHOD error_b.
    "do something and pass the Text ID to _c
    "error_c( ).
  ENDMETHOD.
  METHOD error_c.
    "RAISE EXCEPTION TYPE zcx_gen_exception.
  ENDMETHOD.
ENDCLASS.
 

Now use the button display trigger location, much better:

sap_abap_debugger_trigger_location_direct_raise

Recommendation

Use a wrapper method to determine different prerequisite for raising the exception but keep the RAISE exception. Keep using the benefit of the debugger.

Like It? Share!!

Don't miss an Update

Get notified of the new post, right into your inbox

Naimesh Patel{274 articles}

I'm SAP ABAP Consultant for more than a decade. I like to experiment with ABAP especially OO. I have been SDN Top Contributor.
Follow :

Explore all of his 274 articles.

Load comments

5 Comments

  • Wouter

    What is your preferred approach to class exceptions?
    I prefer 1 generic exc per domain/big development with a return table. My error flow would go via the exception with the error message(s) in the attached return, only catch when needed. Happy flow reports back success/w/i via return table in method params.

  • Steve Oldner

    Start of next year we are upgrading to 7.4, finally. Then I can do the cool stuff!!!

  • Mohinder

    great article.

  • Hello Wouter, I use the TEXT IDs with the message and raise the specific message using the TEXTID when exception has to be raised, and without the wrapper.

    For More than one message type of scenario, I use the separate table in my class instead of creating that as the attribute of the exception class.

    For caller to know where are the messages, we can provide that as part of the exception say refer to xyz attribute for full log – I haven’t done that yet as so far I have been keep on collecting the messages and write them in the App Log before raising the exception where there are more than 1 messages.

    Thanks for bringing up the point.

  • Hello Steve, this can be also applicable to releases prior to 740. I have only used the inline declaration in the example as they are easy to read and less coding 🙂

    Thanks.

Comments on this Post are now closed. If you have something important to share, you can always contact me.

You seem to be new here. Subscribe to stay connected.