on 2015 Jul 02 5:54 PM
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 :
We implemented those methods in order to :
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
Request clarification before answering.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
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.
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
User | Count |
---|---|
76 | |
30 | |
10 | |
8 | |
8 | |
7 | |
7 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.