Nothing happen inside of an async function (send request with easysoap) - node.js

I am new in node.js, and I am experimenting things since a few days already.
Today, I have tried to send a XML request to an API, with the use of easysoap-request.
It worked perfectly, but I would have had to create an XML file for each different query, so I tried with easysoap. Here my code:
const EasySoap = require('easysoap');
console.log("test");
(async () => {
const params = {
host : 'https://comeapi.com',
path : '/dir/soap',
wsdl : '/dir/wsdl',
headers: [{
'user-agent': 'Request-Promise',
'Content-Type': 'text/xml',
}]
}
var soapClient = EasySoap(params);
soapClient.call({
method :'one_methode',
attributes: {
xmlns: 'https://someapi.com'
},
params: {
'api' : {
'authentication' : {
'login' : 'mylogin',
'password' : 'mypassword'
},
'params' : {
'another_params' : {
'name' : 'Brian',
}
}
}
}
}).then((callResponse) => {
console.log(callResponse.data); // response data as json
console.log(callResponse.body); // response body
console.log(callResponse.header); //response header
}).catch((err) => {
throw new Error(err);
});
console.log("test2");
});
console.log("test3");
When I'm starting my file with the node command, it's only shows me "test" and "test 3" in the terminal, instead of the response of the API.
I do not understand the problem in my program because I have already used the "(async () => {" function in previous programs, and that rather well worked.
Thanks for you're help. ^^
Edit: I added the missing part in my code and now there is something new. It's an error, and I don't understand it...
(node:10264) UnhandledPromiseRejectionWarning: Error: Error: no wsdl/xml response
at soapClient.call.then.catch (C:\Users\user\Documents\src\script.js:40:15)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:10264) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10264) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Is this a problem with the .catch() ? Can someone explain me ?
Thanks

Your function is only defined but never called. Call your function at the end of the definition
(async () => {
....
console.log("test2");
})(); // call this function by adding this parenthesis
This is called a IFFY(Immediately-Invoked Function Expression) function in javascript
If you don't want to use a IFFY name your function and call it, like this
const f = async () => {
....
console.log("test2");
}
f()

Your async function needs to be called. Currently you are only declaring a function. To execute it, you need to replace the line before console.log("test3"); by })();

Related

MongooseError: Query was already executed: User.countDocuments({})

(node:9540) UnhandledPromiseRejectionWarning: MongooseError: Query was already executed: User.countDocuments({})
at model.Query._wrappedThunk [as _countDocuments] (D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\mongoose\lib\helpers\query\wrapThunk.js:21:19)
at D:\Acadamic-LANGUAGE-PROJECTS\Angular-Projects\eShop-MEAN STACK\Back-End\node_modules\kareem\index.js:370:33
at processTicksAndRejections (internal/process/task_queues.js:77:11)
(Use node --trace-warnings ... to show where the warning was created)
(node:9540) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node
process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:9540) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
this is my Code......
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments((count) => count)
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
It seems that you are using Mongoose. It seems you are mixing between async-await and callbacks.
Change await User.countDocuments((count) => count) to
await User.countDocuments()
This is because countDocuments() is called using its callback (which passes its result to the callback), while on the other hand, it is also asked to pass its result to the userCount variable using the await command.
This is exactly what this error message is trying to say: hey, you're sending the same query to the database twice ! While, since since v6 of Mongoose, you can only get run query once - ie, either by adding the cbk argument, or using async-await block. Read about it here: https://mongoosejs.com/docs/migrating_to_6.html#duplicate-query-execution
Now let's move ahead to fixing the problem:
I don't completely understand what you're trying to do this in line:
const userCount = await User.countDocuments((count) => count)
I think what you're trying to do is just get the document count. If so, simply drop 'count => count'.
router.get(`/get/count`, async (req, res) =>{
const userCount = await User.countDocuments();
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
If you were to add a filter to the count (which is what the countDocuments gets - a filter; see API here), then you should use the key:value pair form, ie {count: count}.
router.get(`/get/count`, async (req, res) =>{
/* let count; etc. */
const userCount = await User.countDocuments({count: count});
if(!userCount) {
res.status(500).json({success: false})
}
res.send({
userCount: userCount
});
})
Of course you should use a proper try-catch block when using await, to be able to handle the error if thrown.
(Just encountered this problem myself and made some research into it.)
module.exports.getUserCount = async(req,res)=>{
const numberOfUser = await User.countDocuments()
res.send({numberOfUser : numberOfUser});
}

Nodejs Netsuite restless Error : (node:1128) UnhandledPromiseRejectionWarning: Unhandled promise rejection

I am using nodejs npm module netsuite-rest to connect to netsuite rest web services and I am getting this error : UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch bloc
let NetSuiteRestlet = require('netsuite-restlet');
const config = {
account: 'XXXXX',
username: 'XXXXX',
password: 'XXXX',
role: 'FOM PH Sales Manager'
};
const url = 'https://6218235.suitetalk.api.netsuite.com';
const parameters = {
internalid: 1054
};
let ns = new NetSuiteRestlet(config);
// Example using the get function
ns.get(parameters, url).then((out) => { console.log(out) });
It looks like your get request is failing, but is not being handled correctly.
Since you are using promises, you would simply chain on a .catch after the .then to catch the promise rejection.
For example:
ns.get(parameters, URL)
.then((out) => { console.log(out) })
.catch((error) => {
console.log(error) // and/or handle the error some other way
}
See here for more:
How to handle promise rejections: https://flaviocopes.com/javascript-promises-rejection/

ElasticSearch-js { body } is undefined

I am getting this error when running a AWS lambda function to push data into an Elasticsearch instance
I can get it to run if I manually remove the { body } from the node modules, but I can't find why it keeps erroring on that.
my code
client.helpers.bulk({
datasource: docs,
onDocument(doc) {
return {
index: { _index: index , _id: doc.id },
body: doc.body
}
},
onDrop(doc) {
console.log("failed to index ", doc.key);
},
retries: 5,
flushBytes: 1000000,
wait: 10000
})
error
{
"errorType": "Runtime.UnhandledPromiseRejection",
"errorMessage": "TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
"reason": {
"errorType": "TypeError",
"errorMessage": "Cannot destructure property 'body' of 'undefined' as it is undefined.",
"stack": [
"TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
" at /var/task/node_modules/#elastic/elasticsearch/lib/Helpers.js:679:81"
]
},
"promise": {},
"stack": [
"Runtime.UnhandledPromiseRejection: TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.",
" at process.<anonymous> (/var/runtime/index.js:35:15)",
" at process.emit (events.js:314:20)",
" at process.EventEmitter.emit (domain.js:483:12)",
" at processPromiseRejections (internal/process/promises.js:209:33)",
" at processTicksAndRejections (internal/process/task_queues.js:98:32)"
]
}
I was also getting this error when referencing #opensearch-project/opensearch (which is an elasticsearch-js client fork) and using the client.helpers.bulk helper. That was in conjunction with aws-elasticsearch-connector for implementing AWS SigV4 signed API requests.
The error message was as follows:
TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.
at node_modules/#opensearch-project/opensearch/lib/Helpers.js:704:93
It was quite annoying and I was not in the mood for implementing my own OpenSearch client and interacting with the APIs directly, so I dig deeper and found the issue.
How can one reproduce the bug?
I created an isolated test to illustrate the problem. Hopefully it's easily reproducible this way.
import { Client } from '#opensearch-project/opensearch';
import * as AWS from 'aws-sdk';
// My fork of https://www.npmjs.com/package/aws-elasticsearch-connector capable of signing requests to AWS OpenSearch
// #opensearch-project/opensearch is not yet capable of signing AWS requests
const createAwsElasticsearchConnector = require('../modules/aws-oss-connector');
const domain =
'PUT_YOUR_DOMAIN_URL_HERE.es.amazonaws.com';
const index = 'YOUR_TEST_INDEX_NAME';
const bootstrapOSSClient = (): Client => {
const ossConnectorConfig = createAwsElasticsearchConnector(AWS.config);
const client = new Client({
...ossConnectorConfig,
node: `https://${domain}`,
});
return client;
};
const main = async (): Promise<void> => {
try {
console.info('Starting processing');
// TEST DEFINITION
const input = [
{ id: '1', name: 'test' },
{ id: '2', name: 'test 2' },
];
const client = bootstrapOSSClient();
const response = await client.helpers.bulk({
datasource: input,
onDocument(doc: any) {
console.info(`Processing document #${doc.id}`);
return {
index: { _index: index, _id: doc.id },
};
},
});
console.info(`Indexed ${response.successful} documents`);
// END TEST DEFINITION
console.info('Finished processing');
} catch (error) {
console.warn(`Error in main(): ${error}`);
}
};
try {
main().then(() => {
console.info('Exited main()');
});
} catch (error) {
console.warn(`Top-level error: ${error}`);
}
and the result was
$ npx ts-node ./.vscode/test.ts
Starting processing
Processing document #1
Processing document #2
(node:39232) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property 'body' of 'undefined' as it is undefined.
at D:\Development\eSUB\Coronado\git\platform\node_modules\#opensearch-project\opensearch\lib\Helpers.js:704:93
(Use `node --trace-warnings ...` to show where the warning was created)
(node:39232) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:39232) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Indexed 2 documents
Finished processing
Exited main()
Stepping through the code I am able to intercept a single call to node_modules/#opensearch-project/opensearch/lib/Helpers.js:704:93 where
client.bulk() is called
which calls bulkApi() in \opensearch\api\api\bulk.js and returns successfully
await finish() is called in \opensearch\lib\Helpers.js:559
inside \opensearch\lib\Transport.js a call to prepareRequest() is made, ending with return transportReturn
this ends up in request():177 calling
return p.then(onFulfilled, onRejected)
with p being null at that time. That resulted my callback in the AWS Transport class responsible for signing requests to callback to the Helper.js tryBulk() with second parameter undefined, resulting in the Cannot destructure property 'body' error.
What is the expected behavior?
Transport.js implementation of the request should obviously not result in a null p promise issue when callback is passed in the request() call. I logged a bug in the opensearch-js repository.
Workaround
At least for me, this looks to be a problem only when using custom AWS signed requests connector implementation. If your case is similar, a quick workaround involves modifying that implementation Transport class. Here is a quick and dirty hotfix that's specific to aws-elasticsearch-connector.
You need to modify AmazonTransport.js from
class AmazonTransport extends Transport {
request (params, options = {}, callback = undefined) {
...
// Callback support
awaitAwsCredentials(awsConfig)
.then(() => super.request(params, options, callback))
.catch(callback)
}
to
// Callback support
// Removed .then() chain due to a bug https://github.com/opensearch-project/opensearch-js/issues/185
// .then() was calling then (onFulfilled, onRejected) on transportReturn, resulting in a null value exception
awaitAwsCredentials(awsConfig).then();
try {
super.request(params, options, callback);
} catch (err) {
callback(err, { body: null });
}

UnhandledPromiseRejectionWarning: TypeError: cb is not a function in loopback.js

I have the following code:
Orders.js
'use strict';
var OrderService = require('../services/OrderService');
module.exports = function(Orders) {
var orderService = new OrderService(Orders);
Orders.history = function(data, cb) {
console.log("getting history");
orderService.getHistory(data, cb)
.catch(err => cb(err));
};
Orders.remoteMethod('history', {
http: { verb: 'get', path: '/:token/history' },
accepts: [
{ arg: "token", type: "string", required: true },
{ arg: "base_token", type: "string", required: true }
],
returns: { type: 'object', root: true }
});
};
Orderservice.js
function OrderService(Orders){
}
OrderService.prototype.getHistory = async function(token, baseToken, callback){
<some operation>
callback(null, this.validatorService.finalize(buyResult));
}
When I hit this API, I get the following error
node:1996) UnhandledPromiseRejectionWarning: TypeError: cb is not a function
at orderService.getHistory.catch.err (/usr/app/server/models/orders.js:12:18)
at processTicksAndRejections (internal/process/next_tick.js:81:5)
(node:1996) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
| (node:1996) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I have similar code for other models and services, what am I missing?
When you define a remoteMethod the amount of arguments must always be equal to a number of arguments defined in the accepts property of your remoteMethod plus one which is cb. In your case there are two arguments defined in the accepts property, so the function should look like:
Orders.history = function(token, base_token, cb) {
console.log("getting history");
orderService.getHistory(token, cb)
.catch(err => cb(err));
};
I would also recommend you to change your Orders.history to an async function and move away from callbacks completely. Loopback supports async functions/promises starting from version 2. The function can be defined as following:
Orders.history = async function(token, base_token) {
console.log("getting history");
return orderService.getHistory(token); // must return a promise
};
It may require a bit of code refactoring on your side but it allows you to write a cleaner code and you do not have to worry about the exceptions handling all the time (Loopback supports it out of the box for async functions).

proxyReq.setHeader can not set headers after they are sent

i am building a node.js proxy and i want to add a conditional header
proxy.on('proxyReq', (proxyReq, req, res) => {
const realIP = parseHttpHeader(req.headers['x-real-ip'])[0];
const path = parseHttpHeader(req.headers['x-original-uri'])[0];
pAny([
check_ip(realIP) ,
check_path(path) ,
check_geo(realIP)
]).then(result => {
console.log (result , "result " )
if (result) {
proxyReq.setHeader('namespace' , 'foo');
} else {
proxyReq.setHeader('namespace' , 'bar'); }
console.log('sending req ')
});
});
.
async function check_ip(realIP) {
try {
const result = await ipModel.findOne({ip: realIP}).exec()
console.log(realIP , result , "ip")
if (result) {
return true
} else {
return false
}
} catch (e) {
throw e;
}
}
and it works just fine till i use the methos check_ip then i get the error
(node:3793) UnhandledPromiseRejectionWarning: Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ClientRequest.setHeader (_http_outgoing.js:498:3)
at /home/master/IPS/server.js:109:14
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:3793) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3793) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
as the error clearly states i am handeling a promise in the wrong way but i don't know how to fix it i tried using callbacks i tried using await
make the check_ip return a promise and try
function check_ip(realIP) {
return ipModel.findOne({ ip: realIP }).exec();
}

Resources