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: 

llegal statement in Asynchronous RFC call

bharath_padmanabhan
Participant
0 Kudos

Experts,

SAP ISU FQEVENT R468 is used to fetch Invoicing open items. Custom FM with code as below has been attached to R468 event.

FUNCTION zisu_fi_r468_open_sel.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(X_INVOICE_UNIT) TYPE ISU21_INVOICE_UNIT
*" REFERENCE(X_INVOICE_PARAM) TYPE ISU21_INVOICE_PARAM
*" CHANGING
*" REFERENCE(XY_SELTAB) TYPE ISELTAB_T
*" REFERENCE(XY_AGRTAB) TYPE IAGRTAB_T
*"----------------------------------------------------------------------
DATA: lt_rfkn1_attributes TYPE TABLE OF fkk_instpl_attributes,
ls_rfkn1_attributes TYPE fkk_instpl_attributes,
lt_rfkn1_attributes2 TYPE TABLE OF fkk_instpl_attributes,
lv_task TYPE string,
lv_count TYPE n.
CONSTANTS: lc_deactiv_reason TYPE deagd_kk VALUE '07',
lc_mo_dt_infinity TYPE auszdat VALUE '99991231',
lc_mo_main_trans TYPE hvorg_kk VALUE '0200'.
CLEAR: gv_separatetask_done.
*Check if any contract does not have move-out date
READ TABLE x_invoice_unit-t_ever TRANSPORTING NO FIELDS WITH KEY auszdat = lc_mo_dt_infinity.
IF sy-subrc NE 0.
* Check if any of billing documents are final
READ TABLE x_invoice_unit-t_bill_doc TRANSPORTING NO FIELDS WITH KEY erch-hvorg = lc_mo_main_trans.
IF sy-subrc = 0.
* Get all active installment plans
CALL FUNCTION 'FKK_S_INSTPLAN_GETLIST'
EXPORTING
i_vkont = x_invoice_unit-acc-fkkvk-vkont
i_detailed = 'X'
i_open_instplans = 'X'
i_cleared_instplans = ''
TABLES
t_rfkn1_attributes = lt_rfkn1_attributes.
* Deactivate active installment plans
LOOP AT lt_rfkn1_attributes INTO ls_rfkn1_attributes.
lv_count = 1 + lv_count.
CONCATENATE 'Z_R468_DINSTP' lv_count INTO lv_task.
CALL FUNCTION 'ZFKK_S_INSTPLAN_DEACTIVATE' STARTING NEW TASK lv_task DESTINATION 'NONE'
PERFORMING after_deactivate ON END OF TASK
EXPORTING
i_opbel = ls_rfkn1_attributes-opbel
i_deagd = lc_deactiv_reason
i_deman = ''
i_deadt = sy-datum
i_vkont = x_invoice_unit-acc-fkkvk-vkont
EXCEPTIONS
update_error = 1
provide_error = 2
application_fault = 3.
IF sy-subrc <> 0.
MESSAGE e036(zfica_msg) WITH ls_rfkn1_attributes-opbel x_invoice_unit-acc-fkkvk-vkont.
ENDIF.
* Since above FM is using STARTING NEW TASK, need to wait until task is completed
* wait up to 10 seconds.
WAIT FOR ASYNCHRONOUS TASKS UNTIL gv_separatetask_done = 'X' UP TO 10 SECONDS.
* IF gv_separatetask_done IS INITIAL.
CALL FUNCTION 'FKK_S_INSTPLAN_GETLIST'
EXPORTING
i_vkont = x_invoice_unit-acc-fkkvk-vkont
* i_opbel = ls_rfkn1_attributes-opbel
i_detailed = 'X'
i_open_instplans = 'X'
i_cleared_instplans = ''
TABLES
t_rfkn1_attributes = lt_rfkn1_attributes2.
READ TABLE lt_rfkn1_attributes2 TRANSPORTING NO FIELDS WITH KEY opbel = ls_rfkn1_attributes-opbel.
IF sy-subrc = 0.
MESSAGE e036(zfica_msg) WITH ls_rfkn1_attributes-opbel x_invoice_unit-acc-fkkvk-vkont.
ENDIF.
* ENDIF.
CLEAR: gv_separatetask_done.
REFRESH: lt_rfkn1_attributes2.
ENDLOOP.
ENDIF.
ENDIF.
ENDFUNCTION.
FORM after_deactivate USING dummy.
DATA: lvf_vkont TYPE vkont_kk,
lvf_opbel TYPE rfkn1-opbel.

gv_separatetask_done = 'X'.
RECEIVE RESULTS FROM FUNCTION 'ZFKK_S_INSTPLAN_DEACTIVATE'
IMPORTING
o_vkont = lvf_vkont
o_opbel = lvf_opbel
EXCEPTIONS
update_error = 1
provide_error = 2
application_fault = 3.
IF sy-subrc <> 0.
MESSAGE e036(zfica_msg) WITH lvf_opbel lvf_vkont.
ENDIF.

ENDFORM.

Above FM has logic to call async FM which will deactivate the installment plan during move out. This FM is working fine for most of the scenarios except a few where it sporadically gives a short dump as below:

ST22 shows below details where its pointing to standard SAP code with ROLLBACK WORK keyword.

Code inside asynch FM looks as below:

FUNCTION ZFKK_S_INSTPLAN_DEACTIVATE.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(I_OPBEL) TYPE RFKN1-OPBEL
*" VALUE(I_DEAGD) TYPE RFKN1-DEAGD OPTIONAL
*" VALUE(I_DEMAN) TYPE RFKN1-DEMAN OPTIONAL
*" VALUE(I_DEADT) TYPE RFKN1-DEADT OPTIONAL
*" VALUE(I_UPDATE_TASK) TYPE BOOLE_D OPTIONAL
*" VALUE(I_IBLAR) TYPE RFKN1-IBLAR OPTIONAL
*" VALUE(I_INKEY) TYPE RFKN1-INKEY OPTIONAL
*" VALUE(I_RPRDA) TYPE RPRDA9_KK DEFAULT 9
*" VALUE(I_VKONT) TYPE VKONT_KK OPTIONAL
*" EXPORTING
*" VALUE(E_PRINT) TYPE RPRDA9_KK
*" VALUE(O_VKONT) TYPE VKONT_KK
*" VALUE(O_OPBEL) TYPE RFKN1-OPBEL
*" TABLES
*" T_FIMSG STRUCTURE FIMSG OPTIONAL
*" EXCEPTIONS
*" UPDATE_ERROR
*" PROVIDE_ERROR
*" APPLICATION_FAULT
*"----------------------------------------------------------------------
O_OPBEL = I_OPBEL.
O_VKONT = I_VKONT.

CALL FUNCTION 'FKK_S_INSTPLAN_DEACTIVATE'
EXPORTING
i_opbel = I_OPBEL
I_DEAGD = I_DEAGD
I_DEMAN = I_DEMAN
I_DEADT = I_DEADT
I_UPDATE_TASK = I_UPDATE_TASK
I_IBLAR = I_IBLAR
I_INKEY = I_INKEY
I_RPRDA = I_RPRDA
IMPORTING
E_PRINT = E_PRINT
TABLES
T_FIMSG = T_FIMSG
EXCEPTIONS
UPDATE_ERROR = 1
PROVIDE_ERROR = 2
APPLICATION_FAULT = 3.

IF sy-subrc = 0.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
elseif sy-subrc = 1.
Raise UPDATE_ERROR.
elseif sy-subrc = 2.
raise PROVIDE_ERROR.
else.
raise APPLICATION_FAULT . .
ENDIF.
ENDFUNCTION.

Error message looks as below:

Analysis:

1) From the job log, I understand that whenever installment plan reversal doesn't happen as expected, this short dump happens. I checked the code R468 FM code to see what happens when subrc returned from asynch FM is not equal to zero. Current code says below:

Question: Is it correct to write message statement in the receiving results subroutine? I found 2 old notes from 2006:

675042 - RPERF_ILLEGAL_STATEMENT in asynchronous RFC

686710 - ABAP runtime error RPERF_ILLEGAL_STATEMENT

One note says, we are not allowed to use message type warning or information in receiving results subroutine. Other note says that we should not use message statement in this routine.
Question:

1) Short dump point to SAP code with roll back doesn't look like the root cause of this issue to me. If its custom code, then its possible that I might have used rollback in a place where it shouldn't be used. Since its standard code, it makes me believe that an undesirable behavior which is nothing but installment plan couldn't be deactivated occurred due to which roll back had to be called.

I would like to know if we are allowed to use message statement in receiving results routine. I am suspecting that this might be the reason for the short dump.

NOTE: This issue isn't happening frequently. Its sporadic and still we would like to find the root cause and address it.

Apologies for a lengthy post. I wanted to provide as much details as possible to describe the background of my issue.

Please feel free to let me know if you need any additional details.
Kindly help me in this regard.

BR,

Bharath

1 ACCEPTED SOLUTION

Sandra_Rossi
Active Contributor
0 Kudos

MESSAGE TYPE 'E' triggers ROLLBACK WORK, so as said in the short dump, it's not allowed. ABAP Keyword Documentation - Messages - RFC Processing.

I have no idea about R468, functionally speaking, but:

  • What does R468 documentation say?
  • Does it say to not trigger ROLLBACK WORK or any related ABAP statement?
  • Also, any user exit should be used in the way it's described by SAP. Here you are trying to do some UPDATES in a user exit to be used to READ only (according to what you say). I would say that you go wrong by design, and you'd better trigger your code outside of R468 exit.
4 REPLIES 4

Sandra_Rossi
Active Contributor
0 Kudos

MESSAGE TYPE 'E' triggers ROLLBACK WORK, so as said in the short dump, it's not allowed. ABAP Keyword Documentation - Messages - RFC Processing.

I have no idea about R468, functionally speaking, but:

  • What does R468 documentation say?
  • Does it say to not trigger ROLLBACK WORK or any related ABAP statement?
  • Also, any user exit should be used in the way it's described by SAP. Here you are trying to do some UPDATES in a user exit to be used to READ only (according to what you say). I would say that you go wrong by design, and you'd better trigger your code outside of R468 exit.

0 Kudos

Hi Sandra,

Thank you so much for your reply. After getting so much help from you, now when I start posting a thread, I automatically start thinking, what else should I add in the thread so that it will help Sandra understand my problem. As your profile says, ask precise question to get precise answers.

Every single expert here is extremely helpful. I am not disrespecting anyone. I really appreciate every expert take out their valuable time to generously help people like me who come to SCN as a last resort for help after trying all possible options. In my case, I have been extremely lucky to get help from you every single time. I wish I could meet you someday in person to express how much I value your help. If there is a BFF blog about you, please let me know. I would like to read it to know more about you.

Coming to FQEVENT R468, SAP ISU has several events where we can attach custom FMs. These are like BADIs which are hooks in standard SAP code to allow customers to enhance the standard behavior. As you rightly said, we can't use commit or roll back in these events as seen below in event R468 documentation:

I believe that is why the original developer of this FM has created an asynchronous FM to have the commit in a separate LUW.

Based on the job log, we can see Installment plan could not be deactivated custom message. This is triggered when subrc from FM FKK_S_INSTPLAN_DEACTIVATE is not equal to 0.

My question is specifically about message statement in the receiving routine FORM after_deactivate using dummy. Here we see:

 IF sy-subrc <> 0.
MESSAGE e036(zfica_msg) WITH lvf_opbel lvf_vkont.
ENDIF.

From standard help documentation, I couldn't understand if adding message statement in the routine created to receive results is allowed. I feel that short dump is not pointing to actual error. Roll back work is getting executed because installment plan deactivation failed. And when it fails, what happens is this message statement gets executed. But I am not able to say for sure that this might be the culprit. When I look at SAP note 675042, it says below statements are not allowed.

  • - MESSAGE W... and MESSAGE I...

There is no mention about message E.

But if we look at SAP note 686710, it says MESSAGE keyword is not allowed when processing the response of async RFC as seen below:

When processing the responses of an asynchronous RFC, you cannot use any language elements that result in the interruption (that is, either the rolling out or exiting) of the response routine. These language elements include CALL SCREEN, CALL TRANSACTION, CALL DIALOG, SUBMIT, WAIT, COMMIT WORK, ROLLBACK WORK, COMMUNICATION, MESSAGE, STOP, RFCs, RAISE, RAISE EXCEPTION, HTTP/HTTPS/SMTP communication, and so on.

Based on my understanding, message statement should not be written in routine after_deactivate. Instead whatever message statement is present after ON END OF TASK keyword should be sufficient to raise an error message in the job log in case of a failure:

        CALL FUNCTION 'ZFKK_S_INSTPLAN_DEACTIVATE' STARTING NEW TASK lv_task DESTINATION 'NONE'
PERFORMING after_deactivate ON END OF TASK
EXPORTING
i_opbel = ls_rfkn1_attributes-opbel
i_deagd = lc_deactiv_reason
i_deman = ''
i_deadt = sy-datum
i_vkont = x_invoice_unit-acc-fkkvk-vkont
EXCEPTIONS
update_error = 1
provide_error = 2
application_fault = 3.
IF sy-subrc <> 0. " --> This SUBRC check may be sufficient?
MESSAGE e036(zfica_msg) WITH ls_rfkn1_attributes-opbel x_invoice_unit-acc-fkkvk-vkont.
ENDIF.

I would like to know how others do exception handling in case of async FM call. Most of the examples I see online are very simple without exception handling.

BR,

Bharath

0 Kudos

Correct that the documentation (the link I have posted) isn't very clear:

  • "Messages of types A, E, and X cause processing to terminated, followed by a database rollback. In the calling program, the classic exception SYSTEM_FAILURE is raised."

SYSTEM_FAILURE would mean a short dump but doesn't indicate which one it is (maybe RPERF_ILLEGAL_STATEMENT / Statement "ROLLBACK WORK" is not allowed in this form?)

The note 686710 doesn't say more.

Your RFC call is incorrect: in the EXCEPTIONS block, you should have only SYSTEM_FAILURE or COMMUNICATION_FAILURE (see ABAP documentation). It's only in the RECEIVE that you should indicate the ZFKK_S_INSTPLAN_DEACTIVATE exceptions.

Simply initialize a global variable if RECEIVE fails and indicate this global variable in the WAIT UNTIL condition.

Hi Sandra,

I reread your answer and I get it now. Message statement inside exit/fqevent will cause termination in program flow and that is why I see ST22 dump in job log.

I am planning to change my design to simply notify the users whenever there is a failure. This way, job will complete without any dumps and the users will also know that they have to manually intervene to deactivate the installment plan.

Thank you so much, Sandra.

BR,

Bharath