Schedule an Axios POST request - node.js

I got a client that's periodically sending GET requests to get a status of a demand that would've been generated earlier.
If the demand is ready, the server would respond with the information the client requested and should schedule an Axios POST request X minutes later.
Now, I've tried using Promises and setTimeout but they don't seem to work. I'm wondering whether the res.json I'm using is causing some issues.
api.get('/api-gitlab-launcher/request-status', async (gitlabRequest, res, next) => {
requestNb = gitlabRequest.headers['request-nb']
let obj = getRequestInfo(gitlabRequest, requestNb)
if (obj.requestStatus === "Not found") {
res.status(404)
res.send("RequestNb doesn't exist!")
} else if (obj.requestStatus === "Running") {
res.status(400)
res.send("Not finished yet")
} else if (obj.requestStatus === "finished") {
// This code will be scheduled to run after EXPIRATION_TIME
setTimeout(async () => {
let data = new FormData();
data.append("token", DESTROY_TOKEN);
data.append("ref", "terraform-v1");
data.append("variables[LAST_PIPELINE_ID]", pipelineId);
config = {
method: "POST",
url: `https://gitlab.com/api/v4/projects/${PROJECT_ID_DESTROY}/trigger/pipeline`,
data: data,
headers: {
...data.getHeaders(),
},
};
console.log('About to launch POST request')
await axios(config).then(
() => {
console.log("Resources destroyed.");
},
(error) => {
console.log(`error : ${error}`);
}
);
}, EXPIRATION_TIME);
res.status(200);
res.json({ec2Link: obj.ec2InstanceLink});
}
}
)
Am I doing it right? Did something wrong? I'm open to all criticism.
EDIT : The Axios POST request works without the setTimeout() wrap :
START RequestId: 03ee88f5-4abc-4f63-a59c-faa877c4b9f4 Version: $LATEST
END RequestId: 03ee88f5-4abc-4f63-a59c-faa877c4b9f4
REPORT RequestId: 03ee88f5-4abc-4f63-a59c-faa877c4b9f4 Duration: 1396.87 ms Billed Duration: 1400 ms Memory Size: 128 MB Max Memory Used: 91 MB Init Duration: 585.65 ms
START RequestId: 9ffcbec2-6445-422c-87b7-4a5164b0593b Version: $LATEST
END RequestId: 9ffcbec2-6445-422c-87b7-4a5164b0593b
REPORT RequestId: 9ffcbec2-6445-422c-87b7-4a5164b0593b Duration: 5.03 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 91 MB
START RequestId: 3577932d-53ec-4ee0-bf4a-f8aee12eba67 Version: $LATEST
END RequestId: 3577932d-53ec-4ee0-bf4a-f8aee12eba67
REPORT RequestId: 3577932d-53ec-4ee0-bf4a-f8aee12eba67 Duration: 1.60 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 91 MB
START RequestId: ab854edb-5a86-41b1-81de-8bec85a54ad2 Version: $LATEST
END RequestId: ab854edb-5a86-41b1-81de-8bec85a54ad2
REPORT RequestId: ab854edb-5a86-41b1-81de-8bec85a54ad2 Duration: 210.82 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 92 MB
START RequestId: 5f6ae638-ea84-4308-8ea5-6ae3d3fb0116 Version: $LATEST
END RequestId: 5f6ae638-ea84-4308-8ea5-6ae3d3fb0116
REPORT RequestId: 5f6ae638-ea84-4308-8ea5-6ae3d3fb0116 Duration: 516.74 ms Billed Duration: 600 ms Memory Size: 128 MB Max Memory Used: 93 MB
START RequestId: ddeb01ae-c9f6-40b2-ace5-b8b47ed21ebe Version: $LATEST
2020-09-09T20:15:53.893Z ddeb01ae-c9f6-40b2-ace5-b8b47ed21ebe INFO About to launch POST request
2020-09-09T20:15:54.644Z ddeb01ae-c9f6-40b2-ace5-b8b47ed21ebe INFO Resources destroyed.
END RequestId: ddeb01ae-c9f6-40b2-ace5-b8b47ed21ebe
REPORT RequestId: ddeb01ae-c9f6-40b2-ace5-b8b47ed21ebe Duration: 753.89 ms Billed Duration: 800 ms Memory Size: 128 MB Max Memory Used: 93 MB

Change the else if block as follows,
else if (obj.requestStatus === "finished") {
// This code will be scheduled to run after EXPIRATION_TIME
setTimeout(async () => {
let data = new FormData();
data.append("token", DESTROY_TOKEN);
data.append("ref", "terraform-v1");
data.append("variables[LAST_PIPELINE_ID]", pipelineId);
config = {
method: "POST",
url: `https://gitlab.com/api/v4/projects/${PROJECT_ID_DESTROY}/trigger/pipeline`,
data: data,
headers: {
...data.getHeaders(),
},
};
await axios(config).then(
() => {
console.log("Resources destroyed.");
},
(error) => {
console.log(`error : ${error}`);
}
);
}, EXPIRATION_TIME);
res.status(200);
res.json({ ec2Link: obj.ec2InstanceLink });
}
}
Note that EXPIRATION_TIME is in milliseconds.

Related

Random Instant Serverless Function Timeouts

We've been dealing with this issue in our t3 application for over a week now. Here is the error we are getting in the Vercel function logs: 
START RequestId: 3e875969-afce-4409-a7ae-96efc99ff603 Version: $LATEST 2023-01-31T13:43:45.065Z d22a6e7d-0ef6-4aa2-828e-ab70ceb99f02 ERROR Unhandled Promise Rejection  {\"errorType\":\"Runtime.UnhandledPromiseRejection\",\"errorMessage\":\"Error: timeout of 3000ms exceeded\",\"trace\":[\"Runtime.UnhandledPromiseRejection: Error: timeout of 3000ms exceeded\",\" at process.<anonymous> (file:///var/runtime/index.mjs:1194:17)\",\" at process.emit (node:events:525:35)\",\" at process.emit (node:domain:489:12)\",\" at emit (node:internal/process/promises:149:20)\",\" at processPromiseRejections (node:internal/process/promises:283:27)\",\" at process.processTicksAndRejections (node:internal/process/task_queues:96:32)\"]} [ERROR] [1675172625066] LAMBDA_RUNTIME Failed to post handler success response. Http response code: 400. RequestId: 3e875969-afce-4409-a7ae-96efc99ff603 Error: Runtime exited without providing a reason Runtime.ExitError END RequestId: 3e875969-afce-4409-a7ae-96efc99ff603 REPORT RequestId: 3e875969-afce-4409-a7ae-96efc99ff603. Duration: 12.50 ms Billed Duration: 13 ms Memory Size: 1024 MB Max Memory Used: 143 MB"
This only happens to Vercel deployed branches.Notice how it says that it is a 3000ms timeout error but the duration is only 12.50ms.
More details:
All necessary variables (like required user id's for API calls) are provided
The failing API calls succeed most of the time but about 1/5 times they fail.
Includes all our API calls
Example failing API call:
import type { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "../../../server/db/client";
export default async function handler(  
req: NextApiRequest,  res: NextApiResponse) {  
if (req.method === "POST") {    
try {      
const data = JSON.parse(req.body);      
const update = await prisma.user.update({
        where: { id: data.id },
        data: data.data,      
});      
res.json(update);    
} catch (e: any) {      
res.status(500).json({ message: e.message });      
throw new Error("Could't update user:"+ e.message)
    }  
}
}
Note:
The error messages in the catch block are printed nowhere.This is more or less how we call all our serverless functions:
async function updateUserCurrentInstitution({ userId, institutionId }) {  
const response = await fetch(api.updateUser, {
    method: "POST",
    body: JSON.stringify({
      id: userId,
      data: {
        currentInstitution: institutionId,
      },
    }),
  });
  if (!response.ok) {
    throw new Error(response.statusText);
  }
  return response;
}
Any help would be greatly appreciated !

Problems in nodejs callback in custom alexa skill

I am trying to create a custom Alexa skill in which I am calling an API. But somehow my code is behaving weird.
CASE - 1
'firstChance': function () {
// Some code here//
getJSON(options, function (err, result) {
if (err) {
return console.log('ERROR while trying to get country names', err);
}
console.log(result);
});
this.emit(':tell', speechOutput, speechOutput);
},
In this case no errors are shown in cloudwatch but the control is not going to getJSON function eventhough this.emit() function is executed.
Below are the cloudwatch logs:
CloudWatch logs:

13:42:49
START RequestId: ************ Version: $LATEST

13:42:49
2018-04-03T13:42:49.578Z *************** Warning: Application ID is not set

13:42:49
END RequestId: *********************

13:42:49
REPORT RequestId: ************** Duration: 74.03 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 48 MB

13:42:51
START RequestId: ***************** Version: $LATEST

13:42:51
2018-04-03T13:42:51.647Z *********************** Warning: Application ID is not set

13:42:51
END RequestId: *************************

13:42:51
REPORT RequestId: ************************ Duration: 153.09 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 49 MB
CASE 2 :
'firstChance': function () {
// Some code here//
getJSON(options, function (err, result) {
if (err) {
return console.log('ERROR while trying to get country names', err);
}
console.log(result);
});
//this.emit(':tell', speechOutput, speechOutput);
},
In this case even though there are no errors in the logs and the control is going to getJSON, but alexa says "There was a problem with the requested skill's response".
Below are the cloudwatch logs:

13:35:32
START RequestId: ************************** Version: $LATEST

13:35:32
2018-04-03T13:35:32.896Z e16ddc70-3743-11e8-bf3b-a98fb0c89baf Warning: Application ID is not set

13:35:32
END RequestId: **************************

13:35:32
REPORT RequestId: ************************** Duration: 110.81 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 48 MB

13:35:35
START RequestId: ************************** Version: $LATEST

13:35:35
2018-04-03T13:35:35.549Z ************************** Warning: Application ID is not set

13:35:35
2018-04-03T13:35:35.861Z ************************** Response from Server started

13:35:35
2018-04-03T13:35:35.861Z ************************** Server Status: 200

13:35:35
2018-04-03T13:35:35.861Z ************************** Response Headers : {"server":"Cowboy","connection":"close","x-powered-by":"Express","content-type":"application/json; charset=utf-8","content-length":"187238","etag":"W/\"Vhlms2jCBxpTPF7sp9mxAw==\"","vary":"Accept-Encoding","date":"Tue, 03 Apr 2018 13:35:35 GMT","via":"1.1 vegur"}

13:35:35
2018-04-03T13:35:35.978Z ************************** Preparing the hash map...

13:35:36
2018-04-03T13:35:35.978Z ************************** [ { name: { common: 'Afghanistan', official: 'Islamic Republic of Afghanistan', native: [Object] }, tld: [ '.af' ], cca2: 'AF', ccn3: '004', cca3: 'AFG', currency: [ 'AFN' ], callingCode: [ '93' ], capital: 'Kabul', altSpellings: [ 'AF', 'Afġānistān' ], relevance: '0', region:

13:35:36
END RequestId: **************************

13:35:36
REPORT RequestId: ************************** Duration: 1249.65 ms Billed Duration: 1300 ms Memory Size: 128 MB Max Memory Used: 57 MB

13:35:36
START RequestId: ************************** Version: $LATEST

13:35:36
2018-04-03T13:35:36.954Z e46c4ff4-3743-11e8-a19e-036de9469172 Warning: Application ID is not set

13:35:36
END RequestId: **************************

13:35:36
REPORT RequestId: ************************** Duration: 1.97 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 57 MB
I am not able to resolve this.
I think, I have made some mistake in the callback of getJSON().
It looks like getJSON is an asynchronous function: meaning it returns immediately and it calls you back when the results are ready, or when an error is thrown.
So, in your example, getJSON is invoked, but it returns immediately, followed by your call to this.emit(':tell') which ends your handler and sends the respobse back to Alexa before getJSON has a chance to complete and call your anonymous function callback.
To solve, move this.emit(...) inside the callback function you are passing into getJSON
getJSON(options, function (err, result) {
if (err) {
// handle the error
this.emit(':tell', 'Error getting country names');
return console.log('ERROR while trying to get country names', err);
}
console.log(result);
// handle the successful result
this.emit(':tell', 'The country name was retrieved!');
});
Either try this,
'firstChance': function () {
// Some code here//
getJSON(options, function (err, result) {
if (err) {
return console.log('ERROR while trying to get country names', err);
}
console.log(result);
this.emit(':tell', speechOutput, speechOutput);
});
},
Or you can use set timeout :
'firstChance': function () {
// Some code here//
getJSON(options, function (err, result) {
if (err) {
return console.log('ERROR while trying to get country names', err);
}
console.log(result);
});
setTimeout(() => {
this.emit(':tell', speechOutput, speechOutput);
}, 2500)
},
Or you can try Async - Await which are now natively available in AWS Lambda as mentioned here https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/

How can I use slack api in aws lambda?

I want to use IncomingWebhook api of #slack/client in aws lambda function. There is something problems in my code. Please notice me how can I use.
This is my code below
const { IncomingWebhook } = require('#slack/client');
const config = require('./config')
exports.handler = (event, context, callback) => {
const webhook = new IncomingWebhook(config.slack.webHookUrl)
webhook.send('Hello there', function(err, res) {
if (err) {
console.log('Error:', err);
context.fail('fail')
} else {
console.log('Message sent: ', res);
context.succeed('succeed')
}
});
}
And This is my errors
{
"errorMessage": "RequestId: 9e1b4362-259d-11e8-b422-91108e46ebe1
Process exited before completing request"
}
Here is console errors
START RequestId: 9e1b4362-259d-11e8-b422-91108e46ebe1 Version: $LATEST
2018-03-12T02:32:33.215Z 9e1b4362-259d-11e8-b422-91108e46ebe1 TypeError: Cannot set property 'text' of undefined
at IncomingWebhook.send (/var/task/node_modules/#slack/client/dist/IncomingWebhook.js:26:26)
at exports.handler (/var/task/index.js:6:11)
END RequestId: 9e1b4362-259d-11e8-b422-91108e46ebe1
REPORT RequestId: 9e1b4362-259d-11e8-b422-91108e46ebe1 Duration: 85.31 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 31 MB
RequestId: 9e1b4362-259d-11e8-b422-91108e46ebe1 Process exited before completing request
This was due to a bug in the Slack client which was reported here: https://github.com/slackapi/node-slack-sdk/issues/479, and subsequently fixed in https://github.com/slackapi/node-slack-sdk/releases/tag/v4.0.1. A simple upgrade to the latest version (v4.3.1 at the time of writing) will fix this.

"GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)"

I am trying to run a lambda function using request library. I tried to look at some other same issues, but couldnt find exactly the one i needed. Following is my code:
var req = require('request');
var headers = { 'X-AUTH-TOKEN': 'xxxx',
'Content-Type': 'application/json',
'Accept': 'application/json'};
var body = {"name" : "omkarEmailTest", "command_type":"SparkCommand", "language":"notebook", "note_id":"56563", "label":"YetAnotherSparkCluster"};
// Configure the request
var options = {
url: 'http://api.quobole.com/api/v1.2/commands',
method: 'POST',
headers: headers,
body: body,
json: true
};
exports.handler = (event, context, callback) => {
req(options, function (error, response, body) {
console.log(body);
callback(error);
});
}
Following is the log i am getting in my aws lambda console:
Response:
{
"errorMessage": "getaddrinfo ENOTFOUND api.quobole.com api.quobole.com:80",
"errorType": "Error",
"stackTrace": [
"errnoException (dns.js:28:10)",
"GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)"
]
}
Request ID:
"2295eee5-ec11-11e7-a9f4-dfa2f9f62b50"
Function Logs:
START RequestId: 2295eee5-ec11-11e7-a9f4-dfa2f9f62b50 Version: $LATEST
2017-12-28T20:53:20.715Z 2295eee5-ec11-11e7-a9f4-dfa2f9f62b50 undefined
2017-12-28T20:53:20.775Z 2295eee5-ec11-11e7-a9f4-dfa2f9f62b50 {"errorMessage":"getaddrinfo ENOTFOUND api.quobole.com api.quobole.com:80","errorType":"Error","stackTrace":["errnoException (dns.js:28:10)","GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)"]}
END RequestId: 2295eee5-ec11-11e7-a9f4-dfa2f9f62b50
REPORT RequestId: 2295eee5-ec11-11e7-a9f4-dfa2f9f62b50 Duration: 655.79 ms Billed Duration: 700 ms Memory Size: 128 MB Max Memory Used: 33 MB
Any help will be appreciated!!!!

AWS Lambda function never calls the callback

I've created a node lambda function that does a simple call to an Aurora database. When I test the function in the console, the query returns, I can see the results in the log, but the callback never seems to get called and so my lambda function times out. I can't figure out what the problem is. Hopefully someone here can point me to the problem.
var mysql = require("mysql");
module.exports.handler = function(event, context, cb) {
console.log('start\n');
var con = mysql.createConnection({
...
});
console.log('call data\n');
con.query('SELECT * FROM Tags', function(err, rows) {
console.log('Data received from Db:\n');
console.log(rows);
console.log('calling callback');
cb(null, 'Success');
console.log('callback called');
});
console.log('data called\n');
};
The resulting Cloudwatch log is as follows...
2016-07-25T14:20:05.343Z daf5cd6b-5272-11e6-9036-e73ad17006df start
2016-07-25T14:20:05.398Z daf5cd6b-5272-11e6-9036-e73ad17006df call data
2016-07-25T14:20:05.405Z daf5cd6b-5272-11e6-9036-e73ad17006df data called
2016-07-25T14:20:05.440Z daf5cd6b-5272-11e6-9036-e73ad17006df Data received from Db:
2016-07-25T14:20:05.440Z daf5cd6b-5272-11e6-9036-e73ad17006df [
RowDataPacket {
id: 1,
externalId:
'a87ead34de7e',
orgId: 1,
name: 'lacinia sapien',
createdDate: 1448598369,
modifiedDate: 0
},
...,
RowDataPacket {
id: 50,
externalId: '9ebaaab372e3',
orgId: 1,
name: 'et commodo',
createdDate: 1451551837,
modifiedDate: 0
}
]
2016-07-25T14:20:05.483Z daf5cd6b-5272-11e6-9036-e73ad17006df calling callback
2016-07-25T14:20:05.483Z daf5cd6b-5272-11e6-9036-e73ad17006df callback called
END RequestId: daf5cd6b-5272-11e6-9036-e73ad17006df
REPORT RequestId: daf5cd6b-5272-11e6-9036-e73ad17006df Duration: 300000.12 ms Billed Duration: 300000 ms Memory Size: 1024 MB Max Memory Used: 52 MB
2016-07-25T14:25:05.341Z daf5cd6b-5272-11e6-9036-e73ad17006df Task timed out after 300.00 seconds
Thanks to this question...
Lambda Timing out after calling callback
I found the problem. the Node mysql module keeps the connection open until the server closes it unless it is explicitly closed by the handler logic.
So the node event loop never empties and so never returns the callback. In the above code, I did a ...
con.end();
before calling the callback and it worked.

Resources