I will try to be as clear as possible when I ask about this problem.
Context: I have a lambda function and a layer. The layer is a means of sending emails using the AWS SES. The lambda is merely a function that calls this layer to use the AWS SES to send emails. The layer utilizes the "aws-sdk/client-ses" package to serve its purpose.
My problem: whenever I try to invoke my lambda when its calling my layer, I get the following failure on the layer's part:
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'tslib'\nRequire stack:\n- /opt/node_modules/@aws-sdk/client-ses/dist-cjs/index.js\n- /opt/sendTemplatedEmail.js\n- /var/task/src/lambdas/sendTAPEmailHandler.js\n- /var/runtime/index.mjs",
"stack": [
"Runtime.ImportModuleError: Error: Cannot find module 'tslib'",
"Require stack:",
"- /opt/node_modules/@aws-sdk/client-ses/dist-cjs/index.js",
"- /opt/sendTemplatedEmail.js",
"- /var/task/src/lambdas/sendTAPEmailHandler.js",
"- /var/runtime/index.mjs",
" at _loadUserApp (file:///var/runtime/index.mjs:1000:17)",
" at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1035:21)",
" at async start (file:///var/runtime/index.mjs:1200:23)",
" at async file:///var/runtime/index.mjs:1206:1"
]
}
However, if I take the code in the layer and define it in the lambda and use the same "aws-sdk/client-ses" package, all works just fine with no problems.
I have already concluded that the problem is the "aws-sdk/client-ses" package itself, evident by:
- The package of "tslib" is a dependency of the "aws-sdk/client-ses" package.
- This error only ever appears with the aws-sdk package or its sub packages. I already tried with a different package like "date-fns" and it worked like a charm.
I have already researched on this problem but nothing I found was helpful or had any definite answers.
Here's my layer's code:
const { SESClient, SendBulkTemplatedEmailCommand } = require("@aws-sdk/client-ses");
const config = {
credentials: {
accessKeyId: process.env.SLS_AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.SLS_AWS_SECRET_ACCESS_KEY
},
region: process.env.SLS_AWS_EMAIL_REGION
};
const sesClient = new SESClient(config);
const params = ({ source, destinations, templateName }) => ({
Source: source,
Template: templateName,
Destinations: destinations,
DefaultTemplateData: JSON.stringify({
name: "Maria",
orderNumber: "123456"
// TODO: Replace with any default variables you want to pass to the template
}),
});
const command = (emailParams) => new SendBulkTemplatedEmailCommand(params(emailParams));
const sendTemplatedEmail = async (emailParams) => {
try {
const data = await sesClient.send(command(emailParams));
return data
} catch (error) {
// TODO: Log error;
return error;
}
};
module.exports = sendTemplatedEmail
Here's my layer's package.json file:
{
"name": "sendTemplatedEmail",
"version": "1.0.0",
"main": "sendTemplatedEmail.js",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-ses": "^3.272.0"
}
}
Here's my serverless.yml file
service: service_name
frameworkVersion: "3"
provider:
name: aws
runtime: nodejs18.x
profile: serverless_service_name
stage: dev_stage_here
region: region_value_here
environment:
SLS_AWS_REGION: ${env:SLS_AWS_REGION, "SLS_AWS_REGION_VALUE_HERE"}
SLS_AWS_ACCESS_KEY_ID: ${env:SLS_AWS_ACCESS_KEY_ID, "SLS_AWS_ACCESS_KEY_ID_VALUE_HERE"}
SLS_AWS_SECRET_ACCESS_KEY: ${env:SLS_AWS_SECRET_ACCESS_KEY, "SLS_AWS_SECRET_ACCESS_KEY_VALUE_HERE"}
SLS_AWS_EMAIL_REGION: ${env:SLS_AWS_EMAIL_REGION, "SLS_AWS_EMAIL_REGION_VALUE_HERE"}
layers:
SendTemplatedEmail:
path: src/layers/sendTemplatedEmail
name: SendTemplatedEmail
description: Send templated email
compatibleRuntimes:
- nodejs18.x
package:
patterns:
- "!layerSourceTarball.tar.gz"
exclude:
- .gitignore
- README.md
- serverless.yml
- src/layers/**
- src/emailTemplates/**
- .serverless
- .prettierrc.json
- .prettierignore
excludeDevDependencies: true
individually: true
plugins:
- serverless-offline
functions: ${file(./sls/functions.yml):functions}
custom:
serverless-offline:
port: 5000
httpPort: 5000
websocketPort: 5001
lambdaPort: 5002
My machine's current node version is: v16.19.0
Can you please help me figure out the problem? If there's any more additional information that I must provide please let me know and I'll update this post accordingly.
I defined a layer to send emails by utilizing the aws-sdk/client-ses
package. The layer should have worked when I called it from my lambda function but it doesn't.
Things I've tried so far:
- Played around with the node version.
- Played around with the
aws-sdk/client-ses
version. - I researched the internet for possible answers and found none that were helpful.
- Install the "tslib" library manually in the layer's folder.