Scenario:
I have a Node.JS 12.x Lambda that is backing an Alexa Skill. The user asks the skill a question, and the search parameter is sent to my Lambda in a slot. I query the SQL DB using the mssql package, then return the result to the user.
Issue:
If I fetch results from the DB, the Lambda executes the query successfully and returns the result, but then the Lambda times out and Alexa seems to have not received the response. If I remove the DB query and just return a string, it all works just fine.
Suspicions:
I think there may be some issue with the async/await stuff in here. I just can't figure out what the issue is though. I have checked my use of async/await several times
If I left anything out just let me know. Thanks in advance!
Code:
/**
* Intent handler for FindSomething intent
*/
const MyHandler = {
/**
* Determine whether this handler is able to process this input
* @param {Object} handlerInput The input object
*/
canHandle(handlerInput) {
// This part works fine
return util.checkIntentMatch(handlerInput, INTENT_NAME);
},
/**
* Handle the input
* @param {Object} handlerInput The input object
*/
async handle(handlerInput) {
// Extract slot values
const [
searchTerm,
] = [
Alexa.getSlotValue(handlerInput.requestEnvelope, 'search_term'),
];
// Fulfill request
const responseText = await getResponseText(searchTerm);
// Respond
return handlerInput.responseBuilder
.speak(responseText)
.getResponse();
},
};
And then getResponseText
looks like this:
/**
* Get the response text for the query
* @param {string} searchTerm The search term from the user
*/
async function getResponseText(searchTerm) {
let sectorName = await getSectorForTerm(searchTerm);
console.log(`Inside getResponseText. sectorName: ${sectorName}`);
if (!sectorName) return format(NOT_FOUND_LANGUAGE, { searchTerm });
return format(FOUND_LANGUAGE, { searchTerm, sectorName });
}
/**
* Find the sector for a search term
* @param {string} searchTerm The search term from the user
*/
async function getSectorForTerm(searchTerm) {
// ========================================================================
// If I uncomment this line, it works great -- all the way back to the user
// ========================================================================
//return 'fake result';
// Gather prerequisites in parallel
let [
query,
pool
] = await Promise.all([
fs.readFile(path.join(__dirname, 'queries', 'FindQuery.sql'), 'utf8'),
sql.connect(process.env['connectionString'])
]);
console.log('Pre query');
// Run query
let queryResult = await pool.request()
.input('EntityName', sql.TYPES.VarChar, searchTerm)
.query(query);
console.log('Post query');
// Extract result if any
let result = undefined;
if(queryResult.recordset.length > 0) {
result = queryResult.recordset[0]['SectorName'];
}
console.log(`result of getSectorForTerm: ${result}`);
return result;
}
Edit:
Here is what the log looks like. You can see that the file has loaded, the query has executed, and the return statement is hit within ~500ms. Then several seconds pass before the function times out.
Edit 2:
I have structured my index.js like this example from the AWS docs, so I don't have direct access to context
or similar. That can be changed if needed.