amplify-cli: cognito trigger postConfirmation template causes `Invalid lambda function output : Invalid JSON` for async handler, works after removing the generated code in index.js
CLI version: 4.20.0
I use Amplify CLI to generate a postConfirmation cognito trigger,
exports.handler = async (event) => {
try {
// doing some async stuff
} catch (e) {
console.log('error', JSON.stringify(e))
throw e
}
console.log('event2', JSON.stringify(event))
return event
}
Every time I confirmSignUp, I received a 400 code on the clientside Invalid lambda function output: Invalid JSON
Spent a whole night, then this morning I decide to remove all the code in the index.js generated by amplify-cli:
exports.handler = (event, context, callback) => {
const modules = process.env.MODULES.split(',');
for (let i = 0; i < modules.length; i += 1) {
const { handler } = require(`./${modules[i]}`);
handler(event, context, callback);
}
};
As the line here worries me: handler(event, context, callback), as you can see it doesn’t have the await tag when calling lambda, and I don’t know why we need this code in the 1st place, it might be better to explain the why part at the top rather than the logic, the logic is straightforward to understand.
I completely removed this part, and moved my handler here, everything works like a charm now.
As a rough guess, I think the current for loop doesn’t compatible with async handler.
Maybe we should just remove it, and replace it with whatever blahblah.js which is the main js the user needs to edit.
So:
- to prevent things like this to happen
- remove logic that is not user’s concern unless it solves some problems (but i definitely don’t need this when using serverless framework)
- the user does not need to figure out which
.jsfile to edit.
Thanks 😃
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 28 (15 by maintainers)
Commits related to this issue
- fix: add-to-group PostConfirmation Lambda should not throw /** * For some reason, naively returning a value / Promise or throwing an error * will not work as it is specified in the Lambda docs: * ... — committed to ctjlewis/amplify-cli by ctjlewis 3 years ago
- fix: add-to-group PostConfirmation Lambda should not throw /** * For some reason, naively returning a value / Promise or throwing an error * will not work as it is specified in the Lambda docs: * ... — committed to ctjlewis/amplify-cli by ctjlewis 3 years ago
The generated code is emitted based on templates in the CLI source code. Deleting the files in the
amplify/directory would remove the corresponding functionality completely.We have a fix ready and are just working on the final touches. cc @medelman17
/* this file will loop through all js modules which are uploaded to the lambda resource, provided that the file names (without extension) are included in the “MODULES” env variable. “MODULES” is a comma-delimmited string. */ const moduleNames = process.env.MODULES.split(‘,’); const modules = moduleNames.map(name => require(
./${name}));exports.handler = async (event, context, callback) => { for (let i = 0; i < modules.length; i += 1) { const { handler } = modules[i];
// tmp fix seem to work await handler(event, context, callback); context.done(null, event); } };
As I understand it, there are triggers generated by the CLI that do not return events when they are expected to, so these CloudFormation stacks (which run in AWS to power the different parts of the Amplify architecture) fail when they depend on the results of a previous trigger getting passed to the next, which shows up as “Invalid JSON” (because it got
undefined). I had this with the Add User to Groups functionality in #7179.But I am not an expert and am actually pretty new to this CLI and AWS itself. I will ping you ITT if I make any progress on your issue.
@ctjlewis So, it is related to the generated code, right?
I would like but i find the same problem with another places: https://github.com/aws-amplify/amplify-cli/issues/7196
Actually, the CLI is not so much helpful with those errors.
The Amplify CLI generated Lambda function for auth triggers uses “Non-async” handler instead of the async handler, for details, see AWS Lambda doc.
It follow the module package folder structure
In which index.js is the entry point, and it has the exported handler
And custom.js file is the place your enter your code to handle the trigger, which will be invoked by the logic in the index.js This is the template generated by the CLI
Since this is a Non-async handler setup, the exported handler function in custom.js shouldn’t be replaced it with an “Async” style handler, because then the index.js file cannot correctly invoke it. The error you see is Cognito complaining it did not receive the correct response, which should be sent by “callback(null, event)” in the Non-async handler.
When you moved the whole logic directly into the index.js and it worked because you change the entry point handler to Async handler.
@Albert-Gao thanks for reporting we’ll look into it.