2020 Nov 23 4:10 PM
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?
2020 Nov 23 5:49 PM
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.
2020 Nov 23 5:55 PM
2020 Nov 23 6:02 PM
What about if you add CX_ROOT exception to the CATCH block?
This exception will catch any exception.
2020 Nov 24 9:44 AM
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.
2020 Nov 24 9:39 AM
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.
| User | Count |
|---|---|
| 4 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |