EDUCAÇÃO E TECNOLOGIA

Show backend errors in SAPUI5 app using bapiret2_t

Hi everyone,

I’m Daniele Incampo SAPUI5 and HANA’s developer.

I’m writing my first blog post so I hope you will be understanding.

Here is a simple SAPUI5 example of how to show backend errors.

I’m writing this because I found many obstacles during my app development. So I would like to be helpful  for those like me who are novice with SAPUI5.

BACK-END

Into YOURENTITY_GET_ENTITY (my use case) or any other method of ZCL_YOURPROJECT_DPC_EXT (I think it shoud works):

Declaration

 DATA: lo_meco TYPE REF TO /iwbep/if_message_container, lx_busi_exc TYPE REF TO /iwbep/cx_mgw_busi_exception, lt_log TYPE bapiret2_t. 

Code:

(In my case, errors were reported with ‘E’ or ‘A’)

IF lt_log IS NOT INITIAL. "Se vengono restituiti dei messaggi LOOP AT lt_log INTO DATA(ls_log) WHERE type EQ 'E' OR type EQ 'A'. ENDLOOP. IF sy-subrc EQ 0. "Se ci sono messaggi di errore lo_meco = mo_context->get_message_container( ). lo_meco->add_messages_from_bapi( EXPORTING it_bapi_messages = lt_log ). CREATE OBJECT lx_busi_exc EXPORTING message_container = lo_meco. RAISE EXCEPTION lx_busi_exc. ENDIF. ENDIF.

The result will be something like this :

FRONT-END

After creating the project, the structure is like this. We will focus on writing code into the Utilities.js (You can easily find how to create this here: https://blogs.sap.com/2019/04/08/the-utilities.js-file-a-lot-of-useful-functions-and-scripts/ )

After you create, you need to import into your controller like this :

sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel", "sap/m/MessageBox", "./Utilities" ], function (Controller, JSONModel, MessageBox, Utilities) { "use strict";

So now you will be able to use Utilities.js functions into standard Main.Controller.js simply referring with Utilities.function();

After read your entity set, you have to specify success and error functions. You should write something like this:

We will focus on error function, what you will write into success function is irrelevant for this blog post. So, we will retrieve errors from backend in this way:

var a = JSON.parse(response.responseText); var errDetails = a.error.innererror.errordetails; Utilities.manageErrors(errDetails);

That’s why you can see debugging the code:

Utilities.js

That’s how it works for me.
I made something like the sample of MessageView ( https://sapui5.hana.ondemand.com/#/entity/sap.m.MessageView/sample/sap.m.sample.MessageViewInsideDialog ) with some customization like a preview message as title, signal error by severity, exc.

sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel", 'sap/m/Link', "sap/ui/core/Icon", "sap/m/MessageItem", "sap/m/MessageView", "sap/m/Button", "sap/m/Bar", "sap/m/Text", "sap/m/Dialog" ], function (Controller, JSONModel, Link, Icon, MessageItem, MessageView, Button, Bar, Text, Dialog) { "use strict"; return { initMessage: function (errDetails) { // var oLink = new Link({ // text: "Show more information", // href: "http://sap.com", // target: "_blank" // }); var a = this.getText("year"); var oMessageTemplate = new MessageItem({ type: '{type}', title: '{title}', description: '{description}', subtitle: '{subtitle}', counter: '{counter}', markupDescription: '{markupDescription}' // link: oLink }); var aMockMessages = []; for (var i = 0; i < errDetails.length; i++) { var name = errDetails[i].severity; var nameCapitalized = name.charAt(0).toUpperCase() + name.slice(1); var semiDescription = errDetails[i].message.slice(0, 10); semiDescription = semiDescription.concat('...'); var oMockMessage = { type: nameCapitalized, title: semiDescription, description: errDetails[i].message }; aMockMessages.push(oMockMessage); } var oModel = new JSONModel(); oModel.setData(aMockMessages); var that = this; var oBackButton = new Button({ icon: sap.ui.core.IconPool.getIconURI("navback"), visible: false, press: function () { that.oMessageView.navigateBack(); this.setVisible(false); } }); this.oMessageView = new MessageView({ showDetailsPageHeader: false, itemSelect: function () { oBackButton.setVisible(true); }, items: { path: "/", template: oMessageTemplate } }); this.oMessageView.setModel(oModel); this.oDialog = new Dialog({ resizable: true, content: this.oMessageView, state: 'Error', beginButton: new Button({ press: function () { this.getParent().close(); }, text: "Close" }), customHeader: new Bar({ contentMiddle: [ new Text({ text: "Error" }) ], contentLeft: [oBackButton] }), contentHeight: "300px", contentWidth: "500px", verticalScrolling: false }); }, manageErrors: function (errDetails) { this.initMessage(errDetails); this.oMessageView.navigateBack(); this.oDialog.open(); } }; });

And that’s the final result:

We achieved the goal to show errors coming from back-end into our app using Utilities.js and bapiret2_t as type table.

Please comment if you have any queries. Also request you to let me know if any changes required.

Thanks,

Daniele