cancel
Showing results for 
Search instead for 
Did you mean: 

Exception /iwbep/cx_mgw_busi_exception and Error handling

former_member512938
Participant
0 Kudos

Hi dear gurus,

We are working on a FioriApp-like which the main purpose is to create/update Purchase Orders through OData.

We faced many problems, probably due to our lack of SAPUI5 knowledge, but are now able to create and update those POs with SAPUI5 create() method : SAPUI5 SDK - Demo Kit.

The create() method works as expected :

  • it triggers our XXXSE_CREATE_ENTITY from our generated ZCL_YYY_DP_EXT class when we only send the PO header data
  • it triggers our /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY when we send PO header data and its items

We implemented those methods in order to :

  • in the case of XXXSE_CREATE_ENTITY, create PO (using BAPI_PO_CREATE1)
  • int he case of CREATE_DEEP_ENTITY, update PO (using BAPI_PO_CHANGE)

It is now time to handle those BAPIs' returned errors. Message container is used to pass each bapi return to the App :

lre_container = /iwbep/if_mgw_conv_srv_runtime~get_message_container( ).
lre_container->add_message(
      iv_msg_type = ls_return-type
      iv_msg_id = ls_return-id
      iv_msg_number = ls_return-number
      iv_msg_text = ls_return-message
      iv_msg_v1 = ls_return-message_v1
      iv_msg_v2 = ls_return-message_v2
      iv_msg_v3 = ls_return-message_v3
      iv_msg_v4 = ls_return-message_v4
      iv_is_leading_message = lv_is_leading_message
      iv_add_to_response_header = abap_true ).

Everything is fine so far but one thing : the SAPUI5 create() method would never trigger the error callback function. So, we tried to raise an exception (/iwbep/cx_mgw_busi_exception) within the ABAP code so the error callback function is executed. The response of our update request changed from  "HTTP/1.1 201 Created" to " HTTP/1.1 400 Bad Request". I guess that a normal behavior ?

We are using batch request in order to send multiple requests to our back end.

Here is the response of the back end server :

HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 2028
location: http://pathToOurService/PurchaseOrdersSet('')
dataserviceversion: 1.0

{"error":{{"code":"/IWBEP/CX_MGW_BUSI_EXCEPTION","message":"Exception survenue sans erreur spécifique","propertyref":"","severity":"error"}]}}}


HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1059
dataserviceversion: 2.0

{"d":{"__metadata":{"id":"}}


HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 12205
dataserviceversion: 2.0

{"d":{"results":[{"__metadata":{"id":......}}


HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1795
dataserviceversion: 2.0

{"d":{"results":[{"__metadata":{"id":......}]}}


HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 21317
dataserviceversion: 2.0

{"d":{"results":[{"_metadata":{"id":"......}

This seems to be correct, but actually, the 400 Bad Request error makes our App bugging, like there is no oData service plugged. No more data is displayed...

We then tried to disable the batch mode via : JsDoc Report - SAP UI development Toolkit for HTML5 - API Reference - sap.ui.model.odata.ODataModel

And everything went back.

Why a Bad Request sent in response for a batch update, would disable an entire App ?

Is it possible to send a batch with POST request separated from the GET requests ?

Is the  /iwbep/cx_mgw_busi_exception Exception the way we should use to handle the high severity errors ?

Thanks for reading and hope we'll find a solution.

Greetings,

Olivier

Accepted Solutions (1)

Accepted Solutions (1)

former_member182372
Active Contributor
0 Kudos

post your code, preparing batch, odatamodel.create, handlers (suceess and error)

>>Is it possible to send a batch with POST request separated from the GET requests ?


just call submitChanges before you add your POST batch entry, so you will get a "clean" request queue, and call it again when add with adding, so request queue has just one entry

former_member512938
Participant
0 Kudos

Hi Maksim,

Thank you for your answer.

Actually, we do not try to send a batch POST specifically : we only do a "create()" method call after building manually a JSON object we pass to the method. All the other GET requests are data we try to load in our app by SAPUI5 Control Binding.

Please find the concerned code below. It has been excerpt from our Details.controller.js

save: function(oEvent) {

  //Getting the model

  var oModel = oEvent.getSource().getModel();

  //Getting the context

  var oContextData = oEvent.getSource().getBindingContext().getObject();

  //oContextData.PurchaseOrdersItemsSet is empty

  //we want to build it manually from our Table control (this._oNavigationTable) which is bound to the PO items

  var purchaseOrdersItemsSet = this._oNavigationTable.getBinding("items").oLastContextData;

  //temp items array

  var aItems = [];

  //Any modified line ?

  if (Object.keys(oModel.mChangedEntities).length) {

       //let's build the array oContextData.PurchaseOrdersItemsSet

       for (var i in purchaseOrdersItemsSet ) {

           aItems.push(purchaseOrdersItemsSet [i]);

       }

       oContextData.PurchaseOrdersItemsSet = aItems;

 

       //Call the create method

       oModel.create("/PurchaseOrdersSet", oContextData, {

           success: this.onSaveSuccess,

           error: this.onSaveError

       });

       oModel.refresh(true);

  } else {

       //No data change => message

       sap.m.MessageToast.show(this._oResourceBundle.getText("msg.noDataChanged"));

  }

},

//Success Callback function

onSaveSuccess: function(odata, response) {

  sap.m.MessageToast.show(sap.ui.getCore().getMessageManager().getMessageModel().oData[0].message);

  //sap.m.MessageToast.show("succès");

},

//Error Callback function

onSaveError: function(oData, response) {

  sap.m.MessageToast.show(sap.ui.getCore().getMessageManager().getMessageModel().oData[0].message);

  //sap.m.MessageToast.show("error");

},

Here is the part of the view code Details.view.xml. Note that the binding is done via bindItems() method, done in our controller, on routePatternMatched event :

this._oNavigationTable.bindItems({

  path: sURL,

  template: this._oItemTemplate

  });

Details.view.xml :


<Table class="navTableControlLayout" growing="true" growingScrollToLoad="true" id="navigationTable">

     ....

     <ColumnListItem id="navigationListItem">

       <cells id="navigationListItem_cells">

            <Text id="columnFamille_cell" text="{FamilleDescr}"/>

            <Text id="navigationListItem_cells_cell_1" text="{Material}"/>

            <Text id="navigationListItem_cells_cell_2" text="{MaterialDescr}"/>

       </cells>

       </ColumnListItem>

</Table>

As you can see, we don't build a batch call explicitly, but SAPUI5 does so for us. We tried to setUseBatch(false) on the oData and it worked. The application ran back to normal but as we sniffed the HTTP request to our back end server, we saw that multiple requests were sent. We like the way batch is performed, so we want to use it, but don't know why everything stops running when the POST method return the 400 Bad Request HTTP error.

We also tried a submitChange() method call, but this is not a option for us, as it send a POST request for each PO's item (we may have huge amount of items).

Do you know if the raising of :     

RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception.

should result in a Bad Request HTTP error ? From what we understand, it is correct but we are not sure.

Thank you.

Olivier

former_member182372
Active Contributor
0 Kudos

are you using v2 odata model or an old one?

v2 has batchGroupId as parameter, try to give it a unique name:

oModel.create("/PurchaseOrdersSet", oContextData, {

           success: this.onSaveSuccess,

           error: this.onSaveError,

batchGroupId : "mon_unique_batchGroupId"

       });

former_member512938
Participant
0 Kudos

Maksim,

We are using v2 Odata model :

Actually, we already tried this :

oModel.create("/PurchaseOrdersSet", oContextData,
          {success: this.onSaveSuccess,
            error: this.onSaveError,
            batchGroupId: "test",
            changeSetId: "testid" });

We can see it makes different batch calls to the gateway, first one corresponding to our oModel.create() above :

POST PurchaseOrdersSet?sap-client=200 HTTP/1.1

Accept: application/json

Accept-Language: fr-FR

...

GET PurchaseOrdersSet?sap-client=200&$skip=0&$top=20&$inlinecount=allpages HTTP/1.1

Accept: application/json

Accept-Language: fr-FR

...

Here is the answer :

HTTP/1.1 400 Bad Request

Content-Type: application/json

Content-Length: 2397

...


HTTP/1.1 200 OK

Content-Type: application/json

Content-Length: 21324

...

It makes 2 other batch call in order to retrieve the PO data and PO items' data, both with correct response.

But when we make a NavBack() to display the POs list, it seems like nothing got retrieved... The list of POs is empty. When we refresh the list by doing a search with empty string, it retrieves everything fine.

When we click on the PO we tried to change earlier, the list of its items remains empty while every other PO displays their items fine... Same behavior : when we refresh the list of items by doing a search with empty string, it displays all the items...

It's like when a POST request ends to a Bad Request response, everything related to the PO is going crazy.

former_member182372
Active Contributor
0 Kudos

when you create an OdataModel, do you set refreshAfterChange : false?

this might be a good workaround, call refresh excplicetly even after 400 from create

former_member512938
Participant
0 Kudos

Thank you for your answer Maksim.

We do not set refreshAfterChange, it has its default value.

Actually, we already call a refresh(true) after the create() method.

We just try without the refresh(true) method and it seems like everything is doing fine... I can't figure out why this is working... How a refresh can mess up the odata that much ?

We finally don't raise the exception /iwbep/cx_mgw_busi_exception anymore. As we can't understand why this is not working... We thought that busi_exception stood for "business exception", maybe we are wrong... This problem is a big time consumer so we'll handle our return message from the gatway directly in our App, checking whether it is an error or not.

Is that only me or the SAPUI5 documentation is not really explicit ?

Thank your for reading and helping.

Message was edited by: Olivier Souksamran

Answers (0)