I have a lambda function that I wrote a few days ago that was acting totally fine when tested. After going to test it today (without changing any of the code), I receive the following error: "Invalid lambda function output : Invalid JSON"
.
Here is the function code (Node.js 10.x):
const AWS = require("aws-sdk");
const joi = require("@hapi/joi");
const Cognito = new AWS.CognitoIdentityServiceProvider();
exports.handler = async (event) => {
// NOTE: Cognito expects Username to be the user's email
// Vars
const userPoolId = process.env.COGNITO_USER_POOL_ID;
const {email : UNSAFE_EMAIL, language : UNSAFE_LANGUAGE = "en-US"} = event;
// Normalize email and language
const UNSAFE_TRIMMED_EMAIL = UNSAFE_EMAIL.trim();
const UNSAFE_TRIMMED_LANGUAGE = UNSAFE_LANGUAGE.trim();
// Validate UNSAFE_INPUTS
const languageRegex = /^[a-z]{2}-[A-Z]{2}$/;
const schema = joi.object().keys({
email: joi.string().trim().email({minDomainSegments: 2}).required(),
language: joi.string().trim().min(2).max(5).regex(languageRegex).required()
});
const validationResult = joi.validate({
email: UNSAFE_TRIMMED_EMAIL,
language: UNSAFE_TRIMMED_LANGUAGE
}, schema);
if(validationResult.error) {
console.log(JSON.stringify(validationResult.error, null, 2));
return {
statusCode: 400,
body: JSON.stringify({
error: true,
error_message: "Invalid"
})
}
}
// Validation successful, change variable names to reflect
const VALIDATED_EMAIL = UNSAFE_TRIMMED_EMAIL;
const VALIDATED_LANGUAGE = UNSAFE_TRIMMED_LANGUAGE;
// Cognito params
// Username is the user's email
// email is also required in UserAttributes in order to send confirmation
// DesiredDeliveryMediums is required to send confirmation
const params = {
UserPoolId: userPoolId,
Username: VALIDATED_EMAIL,
UserAttributes: [
{
Name: "email",
Value: VALIDATED_EMAIL
},
{
Name: "custom:language",
Value: VALIDATED_LANGUAGE
}
],
DesiredDeliveryMediums: ["EMAIL"]
}
// Attempt to create user in Cognito
try {
const authRes = await Cognito.adminCreateUser(params).promise();
console.log("Success: ", JSON.stringify(authRes, null, 2));
return {
statusCode: 200,
body: JSON.stringify({
success: true
})
}
} catch(err) {
console.log("Error: ", JSON.stringify(err, null, 2));
return {
statusCode: 400,
body: JSON.stringify({
error: true,
error_message: err.message
})
}
}
};
Running the tests, I get the expected error message when passing in badly formatted event data, and I get a Cognito error when attempting to create a user with the same email twice. Again, this is expected. However, when passing in a valid email with no users in the user pool I get the following as my response (formatted for readability):
Response:
{
"statusCode": 400,
"body": {
"error": true,
"error_message": "Invalid lambda function output : Invalid JSON"
}
}
Checking in the Cognito User Pool that this function connects to, I see that a user has been successfully created. Yet, no email has been sent to the email address as was happening a few days ago.
All that is logged is information saying that I have an invalid JSON error, there is no authRes
logged at all. When removing the call to Cognito and the corresponding console.log
call, the try block runs successfully. So the issue is with the call to Cognito.
But why is this code failing today when it was working perfectly a few days ago? That is the part that is making me very frustrated.