Skip to Content
Technical Articles
Author's profile photo Daniele Incampo

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

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Aleksandr karpov
      Aleksandr karpov

      Hi Daniele.

      Good blog. Thanks.

      And why you don't use MessageManager, in my opinion it is mode suitable?

      Author's profile photo Daniele Incampo
      Daniele Incampo
      Blog Post Author

      Hi Aleksandr,

       

      I agree with you.

      However in my use case, the customer wanted something to pop up and I chose MessageView.

       

      Thanks for your comment.

      Author's profile photo Aleksandr karpov
      Aleksandr karpov

      Thanks Daniele.

      You made the right decision