SAPUI5 - Gateway Errors on update method - sapui5

I can't seem to get update methods working in SAPUI5.
Here's the example:
oModel.update("/JobOfflineSet('" + self.jobId + "')", oEntry, {
success: function () {
var oRouter = sap.ui.core.UIComponent.getRouterFor(self);
oRouter.navTo("main", {});
dialog.close();
},
error: function (oError) {}
});
And I'm receiving the following error.
There's no error shown in the SAP Gateway and we aren't even getting into ABAP to debug.
{"error":{"code":"/IWBEP/CM_MGW_RT/022","message":{"lang":"en","value":"The system cannot return your search. Please try again."},"innererror":{"application":{"component_id":"","service_namespace":"/SAP/","service_id":"ZSV_SURVEY_SRV","service_version":"0001"},"transactionid":"306596E88F59F1CD80C7005056BEAC32","timestamp":"","Error_Resolution":{"SAP_Transaction":"","SAP_Note":"See SAP Note 1797736 for error analysis (https://service.sap.com/sap/support/notes/1797736)","Batch_SAP_Note":"See SAP Note 1869434 for details about working with $batch (https://service.sap.com/sap/support/notes/1869434)"},"errordetails":[{"code":"/IWBEP/CX_MGW_BUSI_EXCEPTION","message":"The system cannot return your search. Please try again.","propertyref":"","severity":"error","target":""}]}}}

This is mostly because UI5 is triggering a MERGE method instead of a PUT method (To handle MERGE, Gateway internally makes a GET request, which might be failing). You can specify the update method as 'PUT' in the manifest.json.

Related

Unable to make HTTP Post from custom Karma reporter

I need to publish my Karma test results to a custom REST API. To handle this automatically, I've written a custom Karma reporter. I'm trying to use the run_complete event so that the POST happens after all browsers finish. However, no HTTP call is being made.
I'm using Axios 0.19.2 to do the actual HTTP call, but the same thing happens with node-fetch. The tests are being run by the Angular cli via ng test. My Karma config is lengthy but other than having a million different reporters and possible browser configs, is pretty much standard.
This is my onRunComplete method:
self.onRunComplete = function () {
var report = ... ; // logic to generate a JSON object, not relevant
var url = '...'; // the endpoint for the request
try {
console.log('Sending report to ' + url);
axios.post(url, report, {headers: {'Content-Type': 'application/json'}})
.then(function(response) {
console.log('Success!');
console.log(response);
})
.catch(function(error) {
console.log('Failure!');
console.log(error);
});
} catch (err) {
console.log('Error!');
console.log(err);
}
}
At the end of the test run, it writes to console the 'Sending report to...' message, and then immediately ends. The server does not receive the request at all.
I also tried adding explicit blocking using a 'inProgress' boolean flag and while-loop, but that pretty much just leaves the entire test run hanging since it never completes. (Since the request is never made, the 'inProgress' flag is always true and we never hit the then/catch promise handlers or the catch block.)
I have verified that the Axios POST request works by taking the entire contents of the onRunComplete as shown here, putting it in its own JS file, and calling it directly. The report logs as expected. It's only when I call from inside of Karma that it's somehow blocked.
Since Karma's documentation pretty much boils down to "go read how other people did similar things!" I'm having trouble figuring out how to get this to work. Is there a trick to getting an HTTP request to happen inside of a custom reporter? Why does my implementation not work?
Looks like the post request is made asynchronously - that is the request is made and control resumes almost immediately to the method which completes... try instead:
self.onRunComplete = function () {
var report = ... ; // logic to generate a JSON object, not relevant
var url = '...'; // the endpoint for the request
try {
console.log('Sending report to ' + url);
await axios.post(url, report, {headers: {'Content-Type': 'application/json'}})
...
}
}

'then is not a function' in MongoDB Stitch Webhook

The MongoDB Stitch Webhook docs describe my precise use case: using a POST method to call insertOne then return the inserted _id.
I pasted the example below (directly from the docs) into the Stitch Function Editor.
exports = function(payload, response) {
const mongodb = context.services.get("mongodb-atlas");
const requestLogs = mongodb.db("test").collection("requestlogs");
requestLogs.insertOne({
body: EJSON.parse(payload.body.text()),
query: payload.query
}).then(result => {
response.setStatusCode(201);
response.setBody(result.insertedId);
})
};
I executed the function in the Function Editor console by calling:
exports({query: {arg1: 'hello', arg2: "world!"}, body:BSON.Binary.fromText('{"msg": "world"}')})
An error is returned indicating that .then is not a function.
error: TypeError: 'then' is not a function
Are the docs wrong, or I have I gone astray?
Certain methods, like .then, throw errors in the function editor. In my case, this was a shortcoming of the function editor, rather than an error in my code. Calling the webhook with fetch or Postman, the function executed as expected.
The Incoming Webhook docs contain a special note:
If you want to debug a webhook function response from the function
editor, you must manually provide the HTTP response object when you
run the function.
exports( { body: "This document is the webhook payload" }, new
HTTPResponse() )
That alerted me to the idiosyncratic nature of the function editor as a JS handler. Using Postman I confirmed the function ran without errors when called. The error generated by the function editor was a red herring.

Hook for REST validation with sailsjs

I need to create a validation layer for my REST services, I'm using sailsjs.
Someone know how can I do that?
I tried to create a hook but I cant access routes definitions and the hook is called before start policies :'(
The way is something like picture below.
It is perfectly fine to use policies to pre-process requests before they are passed to the controllers. Policies are not just for authentication and acl. They are so versatile you can use them for anything.
E.g.
policies/beforeUpdateTicket.js
module.exports = function(req, res, ok) {
TicketService.checkTicket(req.params.id, null, true).then(function(ticket) {
# You can even modify req.body
req.body.checked = true;
return ok();
}).fail(function(err) {
# Don't go to the controller, respond with error
return res.send(JSON.stringify({
message: 'some_error'
}), 409);
});
};

Empty response on long running query SailsJS

I'm currently running SailsJS on a Raspberry Pi and all is working well however when I execute a sails.models.nameofmodel.count() when I attempt to respond with the result I end up getting a empty response.
getListCount: function(req,res)
{
var mainsource = req.param("source");
if(mainsource)
{
sails.models.gatherer.find({source: mainsource}).exec(
function(error, found)
{
if(error)
{
return res.serverError("Error in call");
}
else
{
sails.log("Number found "+found.length);
return res.ok({count: found.length});
}
}
);
}
else
{
return res.ok("Error in parameter");
}
},
I am able to see in the logs the number that was found (73689). However when responding I still get an empty response. I am using the default stock ok.js file, however I did stick in additional logging to try to debug and make sure it is going through the correct paths. I was able to confirm that the ok.js was going through this path
if (req.wantsJSON) {
return res.jsonx(data);
}
I also tried adding .populate() to the call before the .exec(), res.status(200) before I sent out a res.send() instead of res.ok(). I've also updated Sails to 11.5 and still getting the same empty response. I've also used a sails.models.gatherer.count() call with the same result.
You can try to add some logging to the beginning of your method to capture the value of mainsource. I do not believe you need to use an explicit return for any response object calls.
If all looks normal there, try to eliminate the model's find method and just evaluate the request parameter and return a simple response:
getListCount: function(req, res) {
var mainsource = req.param("source");
sails.log("Value of mainsource:" + mainsource);
if (mainsource) {
res.send("Hello!");
} else {
res.badRequest("Sorry, missing source.");
}
}
If that does not work, then your model data may not actually be matching on the criteria that you are providing and the problem may lie there; in which case, your response would be null. You mentioned that you do see the resulting count of the query within the log statement. If the res.badRequest is also null, then you may have a problem with the version of express that is installed within sailsjs. You mention that you have 11.5 of sailsjs. I will assume you mean 0.11.5.
This is what is found in package.json of 0.11.5
"express": "^3.21.0",
Check for any possible bugs within the GitHub issues for sailsjs regarding express and response object handling and the above version of express.
It may be worthwhile to perform a clean install using the latest sailsjs version (0.12.0) and see if that fixes your issue.
Another issue may be in how you are handling the response. In this case .exec should execute the query immediately (i.e. a synchronous call) and return the response when complete. So there should be no asynchronous processing there.
If you can show the code that is consuming the response, that would be helpful. I am assuming that there is a view that is showing the response via AJAX or some kind of form POST that is being performed. If that is where you are seeing the null response, then perhaps the problem lies in the view layer rather than the controller/model.
If you are experiencing a true timeout error via HTTP even though your query returns with a result just in time, then you may need to consider using async processing with sailjs. Take a look at this post on using a Promise instead.

Query option 'Format' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings

I'm getting an exception on my Web API controller endpoint and I would appreciate some help solving it.
Here is the story:
In my Web API project, a controller exposes the following endpoints:
My Kendo UI Datagrid makes the following request:
http://localhost:63865/api/employees/GetAll?$callback=jQuery21109420544053427875_1410883352953&%24inlinecount=allpages&%24format=json&%24top=5
I'm getting this exception when validating the ODataQueryOptions sent in the request:
Query option 'Format' is not allowed. To allow it, set the 'AllowedQueryOptions' property on EnableQueryAttribute or QueryValidationSettings.
But I've enabled all query options:
[EnableQuery(AllowedQueryOptions=AllowedQueryOptions.All)]
What am I doing wrong ?
Finally manage to get to the bottom of this!
After creating the ODataValidationSettings object I needed to change the AllowedQueryOptions to AllowedQueryOptions.All. Be default all options are there except the Format and SkipToken.
Anyway, hope this may help anyone else facing the same issue.
I had the same issue but I had to solve it a different way. My OData service controll was generated using Entity Framework (data first) and it turns out Microsoft's template doesn't support all the OData parameters. This puzzled me because I don't need the extra parameters anyway because I was just trying to define a datasource for use with a TreeView Kendo component. I finally found the Telerik blog post that went into detail about Using Kendo UI With MVC4, WebAPI, OData And EF which focussed on the 'inlinecount' param but for me the culprit was the 'format' param.
I'm pasting the summary from that page here in case the link goes bad.
Remove Inline Count Parameter
transport: {
read: {
url: "/api/Albums", // <-- Get data from here
dataType: "json" // <-- The default was "jsonp"
},
parameterMap: function (options, operation) {
var paramMap = kendo.data.transports.odata.parameterMap(options);
delete paramMap.$inlinecount; // <-- remove inlinecount parameter
delete paramMap.$format; // <-- remove format parameter
return paramMap;
}
}