Application Development and Automation 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: 
Read only

Shared Memory - handling cx_shm_build_failed exception

jiri_medved
Participant
0 Likes
3,376

Hello Experts,

I use shared memory for caching personal data from external system. The build method looks like following

METHOD if_shm_build_instance~build.

* Autoload of SHMO (first time use, after system restart and so on)

  DATA: lcl_ldap TYPE REF TO zcl_ldap,
        lcl_ldap_root TYPE REF TO zcl_ldap_root,
        lx_exception TYPE REF TO cx_root.

  TRY.
      lcl_ldap = zcl_ldap=>attach_for_write( ).
    CATCH cx_shm_error INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  TRY.
      CREATE OBJECT lcl_ldap_root AREA HANDLE lcl_ldap.
      lcl_ldap->set_root( lcl_ldap_root ).
      lcl_ldap_root->set_staff( ).
      lcl_ldap->detach_commit( ).
    CATCH cx_shm_error zcx_ldap_not_reachable
      INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  IF invocation_mode = cl_shm_area=>invocation_mode_auto_build.
    CALL FUNCTION 'DB_COMMIT'.
  ENDIF.

the method set_staff( ) gets the data from an external system and populates the shared memory. It raises ZCX_LDAP_NOT_REACHABLE if calling the external system fails.

In the main program I attach the shared memory like following:

...
  DO 10 TIMES.
    TRY.
        lcl_ldap_shmo = zcl_ldap=>attach_for_read( ).
      CATCH cx_shm_inconsistent.
        zcl_ldap=>free_area( ).
      CATCH cx_shm_no_active_version
      cx_shm_read_lock_active
      cx_shm_change_lock_active
      cx_shm_exclusive_lock_active
      INTO lv_exception.
    ENDTRY.

    IF lcl_ldap_shmo IS NOT INITIAL.
      EXIT.
    ENDIF.
    WAIT UP TO 2 SECONDS.
  ENDDO.
...

It works fine if no exception is raised in the set_staff() method.

But if ZCX_LDAP_NOT_REACHABLE is raised the ATTACH_FOR_READ method raises CX_SHM_NO_ACTIVE_VERSION exception and there is a short dump of uncaught exception CX_SHM_BUILD_FAILED in ST22.

How can I catch the exception in order to avoid the short dump?

Hello Experts,

I use shared memory for caching personal data from external system. The build method looks like following

METHOD if_shm_build_instance~build.

* Autoload of SHMO (first time use, after system restart and so on)

  DATA: lcl_ldap TYPE REF TO zcl_ldap,
        lcl_ldap_root TYPE REF TO zcl_ldap_root,
        lx_exception TYPE REF TO cx_root.

  TRY.
      lcl_ldap = zcl_ldap=>attach_for_write( ).
    CATCH cx_shm_error INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  TRY.
      CREATE OBJECT lcl_ldap_root AREA HANDLE lcl_ldap.
      lcl_ldap->set_root( lcl_ldap_root ).
      lcl_ldap_root->set_staff( ).
      lcl_ldap->detach_commit( ).
    CATCH cx_shm_error zcx_ldap_not_reachable
      INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  IF invocation_mode = cl_shm_area=>invocation_mode_auto_build.
    CALL FUNCTION 'DB_COMMIT'.
  ENDIF.

the method set_staff( ) gets the data from an external system and populates the shared memory. It raises ZCX_LDAP_NOT_REACHABLE if calling the external system fails.

In the main program I attach the shared memory like following:

...
  DO 10 TIMES.
    TRY.
        lcl_ldap_shmo = zcl_ldap=>attach_for_read( ).
      CATCH cx_shm_inconsistent.
        zcl_ldap=>free_area( ).
      CATCH cx_shm_no_active_version
      cx_shm_read_lock_active
      cx_shm_change_lock_active
      cx_shm_exclusive_lock_active
      INTO lv_exception.
    ENDTRY.

    IF lcl_ldap_shmo IS NOT INITIAL.
      EXIT.
    ENDIF.
    WAIT UP TO 2 SECONDS.
  ENDDO.
...

It works fine if no exception is raised in the set_staff() method.

But if ZCX_LDAP_NOT_REACHABLE is raised the ATTACH_FOR_READ method raises CX_SHM_NO_ACTIVE_VERSION exception and there is a short dump of uncaught exception CX_SHM_BUILD_FAILED in ST22.

How can I catch the exception in order to avoid the short dump?

5 REPLIES 5
Read only

nmirandaghn
Active Participant
0 Likes
2,665

Add the exception ZCX_LDAP_NOT_REACHABLE to the CATCH block.

Hope it helps.

    TRY.
        lcl_ldap_shmo = zcl_ldap=>attach_for_read( ).
      CATCH cx_shm_inconsistent.
        zcl_ldap=>free_area( ).
      CATCH cx_shm_no_active_version
      cx_shm_read_lock_active
      cx_shm_change_lock_active
      cx_shm_exclusive_lock_active 
      zcx_ldap_not_reachable " <--- Exception added
      INTO lv_exception.
    ENDTRY.
Read only

0 Likes
2,665

Unfortunately that does not work.

Read only

0 Likes
2,665

What about if you add CX_ROOT exception to the CATCH block?

This exception will catch any exception.

Read only

0 Likes
2,665

I can catch the exception cx_shm_no_active_version. But there is always short dump in ST22. The auto build of the shared memory is executed in a separate thread and the exception is not propagated to the calling thread.

I have found a workable solution - see my answer. Any comments highly welcomed.

Read only

jiri_medved
Participant
2,665

I went through several SAP standard implementations of the interface IF_SHM_BUILD_INSTANCE. I could not find any common clear pattern in these implementations how to implement the method BUILD in the "right" way. I have noticed though that none of the implementations throw an exception in case the set method is not succesful.

I have modified my implementation in the following way.

METHOD if_shm_build_instance~build.

* Autoload of SHMO (first time use, after system restart and so on)

  DATA: lcl_ldap TYPE REF TO zcl_ldap,
        lcl_ldap_root TYPE REF TO zcl_ldap_root,
        lx_exception TYPE REF TO cx_root.

  TRY.
      lcl_ldap = zcl_ldap=>attach_for_write( ).
      CREATE OBJECT lcl_ldap_root AREA HANDLE lcl_ldap.
      lcl_ldap->set_root( lcl_ldap_root ).
    CATCH cx_shm_error
      INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  TRY.
      lcl_ldap_root->set_staff( ).
  CATCH zcx_ldap_not_reachable.
      lcl_ldap->detach_rollback( ).
      RETURN.
  ENDTRY.

  TRY .
      lcl_ldap->detach_commit( ).
    CATCH cx_shm_error INTO lx_exception.
      RAISE EXCEPTION TYPE cx_shm_build_failed
        EXPORTING
          previous = lx_exception.
  ENDTRY.

  IF invocation_mode = cl_shm_area=>invocation_mode_auto_build.
    CALL FUNCTION 'DB_COMMIT'.
  ENDIF.
ENDMETHOD.

I am not sure if my implementation is 100% correct but it works - there are no short dumps in ST22 even if the third party system is not reachable.