Display Error message after oData Update - odata

I perform an update via my OData service like this:
oModel.create('/Carriers', oEntry, null, function () {
oModel.refresh();
sap.m.MessageBox.show("Saved", sap.m.MesESS);
}, function (err) {
var message = $(err.response.body).find('message').first().text();
sap.m.MessageBox.show(message, sap.m.MessageBox.Icon.ERROR);
});
If I get an error message in the response I am unable to display the message text.
I create the error like this:
CALL METHOD lo_message_container->add_message_text_only
EXPORTING
iv_msg_type = 'E'
iv_msg_text = msg_text.
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = lo_message_container.
ENDIF.
The err.response.body looks like this:
"{"error":{"code":"SY/530","message":{"lang":"en","value":"This
is the error I am trying to show)"},
"innererror":{"transactionid":"B20B61E5143BF10E92CB000C29D28D3A","timestamp":"20150922092421.4230000","Error_Resolution":{"SAP_Transaction":"Run
transaction /IWFND/ERROR_LOG on SAP NW Gateway hub system and search
for entries with the timestamp above for more details","SAP_Note":"See
SAP Note 1797736 for error analysis
(https://service.sap.com/sap/support/notes/1797736)"},"errordetails":[{"code":"","message":"This
is the error I am trying to show
","propertyref":"","severity":"error","target":""},{"code":"/IWBEP/CX_MGW_BUSI_EXCEPTION","message":"","propertyref":"","severity":"error","target":""}]}}}"
I was trying this but it does not work...
var message = $(err.response.body).find('message').first().text();
sap.m.MessageBox.show(message, sap.m.MessageBox.Icon.ERROR);

It looks like your error is mistaking JSON for a DOM object.
jQuery (the $-sign function) is meant to select DOM elements with the tag name, classes or the id.
To find the right key in an JSON structure, you can use normal JavaScript dot- or brackets-notation:
var message = err.response.body.error.message.value;

Related

Get Response from CREATE_STREAM

We upload a document from SAPUI5 to our SAP System using the CREATE_STREAM Method of the oData Service in ABAP. The creation of the document works fine.
What we would like to achieve is to get the response back to SAPUI5. Especially when there is an error during the creation of the document in the backend.
In Frontend we use the uploadSet Control.
...oUploadSet.uploadItem(oItem);
In the Backend we create a message with
...lo_message_container->add_message( iv_msg_type = /iwbep/cl_cos_logger=>error
iv_msg_number = '018'
iv_msg_id = lv_msg_id
iv_add_to_response_header = abap_true
)....
We can find the created message in the error protocol of our gateway server (/IWFND/ERROR_LOG). But how can this message be retrieved in SAPUI5 and used in the MessageManger Control?
We tried the onUploadCompleted Control but we can't find any response data there.
Can somebody explain how the response or a message header from the CREAT_STREAM method can be used in SAPUI5?
The "new" UploadSet control is kinda half-baked imo. The response will get lost in some internal method. This internal method will then trigger onUploadCompleted and you get nothing but useless information.
Lucky for us we can easily overwrite this internal stuff. UploadSet has an aggregation Uploader. We have to provide our own Uploader. Problem solved. Here is the line that needs to be modified.
sap.ui.define([
"sap/m/upload/Uploader",
...
], function (Uploader, ...) {
return Uploader.extend("my.custom.control.Uploader", {
uploadItem: function (oItem, aHeaders) {
// beginning of the method. take it from the official sources
oXhr.onreadystatechange = function () {
const oHandler = that._mRequestHandlers[oItem.getId()];
if (this.readyState === window.XMLHttpRequest.DONE && !oHandler.aborted) {
// we need to return the xhr object. it contains the response!
that.fireUploadCompleted({ item: oItem, xhr: oXhr });
}
};
// .. rest of the method
}
});
});
Use it like this
<mvc:View xmlns:custom="my.custom.control" ....>
<UploadSet items="....">
.....
<uploader>
<custom:Uploader uploadUrl="......"
uploadCompleted=".onUploadCompleted"
uploadStarted=".onUploadStarted" />
</uploader>
</UploadSet>
Edit: Your own uploader also means implementing your own event handlers (uploadAborted, uploadCompleted, uploadProgressed, uploadStarted). See the official documentation for more information about the events.

How to perform OData V2 read with date as part of the entity primary keys [duplicate]

This question already has an answer here:
Performing OData V2 methods with "Edm.DateTime" as part of primary keys
(1 answer)
Closed 23 days ago.
I am confused on the date format to be used while invoking OData read operation where parameters are mentioned within entityset brackets. Would be great if you can paste your answer against each
How to use ODataModel's read() method if we have values to be passed within the entity set parameters?
var sPath ="/EMP_DETAILSSet(Empid='50160458'/*, ...*/)";
oBackEndModel.read(sPath, {
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
Is this the approach to be followed? Or do we have any other approach?
How to set date as entity set key parameter with OData? Please correct the below code snippet (which gives me bad request error at runtime) where dBegDate and dEndDate are JS standard date objects.
var sPath ="/EMP_DETAILSSet(Empid='50160458',Begdate="+ dBegDate.toJSON() + ",Enddate=" + dEndDate.toJSON() + ",HAFId=' ')";
oBackEndModel.read(sPath, {
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
How to execute multiple expand operation along with the entityset parameters mentioned above? Please fix the error in the below code as it is not working for me.
var sPath ="/EMP_DETAILSSet(Empid='50160458',Begdate="+ dBegDate.toJSON() + ",Enddate=" + dEndDate.toJSON() + ",HAFId=' ')";
oBackEndModel.read(sPath, {
urlParameters: {
$expand: "NAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES"
},
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
Further updates
I have followed the suggestion b Sunil. sPath looked as follows at runtime:
"/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=' ')"
When I tried this, it gave me the following error:
2018-06-13 10:56:31.872300 The following problem occurred: HTTP request failed404,Not Found,{"error":{"code":"005056A509B11EE1B9A8FEC11C21D78E","message":{"lang":"en","value":"Resource not found for the segment '49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=''."},"innererror":{"transactionid":"5B20F78A93457852E10000000ACD4014","timestamp":"20180613052610.2725590","Error_Resolution":{"SAP_Transaction":"Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details","SAP_Note":"See SAP Note 1797736 for error analysis ..."}}}}
Do you know why?
Please note that the following URL works fine and returned the result when executed from SAP Gateway Client:
/sap/opu/odata/XXX/YYYY_SRV/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=' ')?$expandNAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES&$format=json
First thing is to check, what is the primitive type defined in you SAP Netweaver gateway.
Most probably, it will beEdm.DateTime. You can get this info using $metdata call on service.
OData has standard representation of Edm.DateTime
datetime'yyyy-mm-ddThh:mm[:ss[.fffffff]]'
NOTE: Spaces are not allowed between datetime and quoted portion. datetime is case-insensitive
Example : datetime'2000-12-12T12:00'
If its JSON Format representation,
Example: "FlightDate": "/Date(1354665600000)/"
It should look something like:
var sPath = "/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'2014-03-11T14:49:52',HAFId = ' ')";
oBackEndModel.read(sPath, {
urlParameters: {
$expand: "NAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES"
},
success: jQuery.proxy(this._fGetDetailsSuccess, this),
error: jQuery.proxy(this._fBackEndInvocationError, this)
});

datatables.net: Error handling for server side processing

I've setup datatables.net with server side processing on a MVC application using the DataTables.Aspnet.Core & DataTables.AspNet.WebApi2 nugets. All works well and the data gets loaded and displayed fine.
If there is an issue on the server side I catch the exception and return a result containing my custom error message:
// IDataTablesRequest tableRequest
return new DataTablesJsonResult(Response.Create(tableRequest, "my custom error message"), Request);
On the client side I've registered to the error event as well:
$.fn.dataTable.ext.errMode = 'none';
this.$dataTable.on('error.dt', this.onDataTableError.bind(this));
This also works fine, I can parse the response and check for my custom message.
Now the issue: After handling the error I always get the dreaded Uncaught TypeError: Cannot read property 'length' of undefined I assume this is the case because I don't send any data to the client?
How can I prevent this error?
I could not manage to fix this on the server side by adding an empty dataset as this would not be passed with the json.
What I ended up doing is ensuring there is always a data array on the client side:
// register to ajax request event
this.$dataTable.on('xhr.dt', this.afterAjax.bind(this));
// set empty array to make sure we have no issue
// with null references on data.length for loop
afterAjax(event: JQueryEventObject, settings: any, payload: any, response: any): void {
payload.data = payload.data || [];
}

Create New Row in database using Odata

I have an OData Service that is pointing to a table in the database. I want to enter a new record in the table based on the details from user.
I am using the .create method, but the data doesn't seem to get entered in table.
oView=this.getView();
var df = {};
var name = oView.byId("__input3").getValue();
var goal = oView.byId("__area0").getValue();
df.NAME = name;
df.GOAL = goal;
df.TYPE = "type";
df.THEME = "Theme";
var oModel1= new sap.ui.model.odata.ODataModel("/GDH_OData/services/df.xsodata/");
oModel1.create('/Df', df, null, function() {
alert("SUCCESS");
}, function() {
alert("FAIL");
});
Please help where I am going wrong
you're not giving a lot of info, here...
what is the result of your create call ? SUCCESS or FAIL ? if the later, what is the error message returned ? the following error function can help you on this
function(error) {
var message = $(error.response.body).find('message').first().text();
console.log(message);
alert(message);
}
Is the creation code in the backend called (if you put an external breakpoint in your service, do you get the debugger ?) if so, what is the result of debugging step-by-step ?
edit
if there is a "forbidden" response, then you should check the result of transaction su53 for the user. You'll probably have a failed autorization. Then it's just adding the service to your role autorisation.
PS : its better to add your answer to my questions(s) in your question, under a "edit" or "more information" than to put it as another answer. Thus there is only one place to check for the whole problem.
regards
The result is Fail and the error is "Failed to load resource: the server responded with a status of 403 (Forbidden)"

IMapX Gmail SEARCH operation throws exception "Bad or not correct search query"

I have used the ImapX library to SEARCH Gmail using queries like :
ImapX.MessageCollection msg= c.Folders["INBOX"].Search("SUBJECT <abc>", false);
I get the error above when I try and retrieve a message using
MessageCollection msg= client.Folders["INBOX"].Search("UID <abc>", false);
where i have previously established the UID using the MessageUID property which IMapx exposes on an specific message, I get the same error when trying to use the MessageId property.
ImapX.MessageCollection msg= c.Folders["INBOX"].Search("SUBJECT abc", false);

Resources