1

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:

  1. The package of "tslib" is a dependency of the "aws-sdk/client-ses" package.
  2. 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:

  1. Played around with the node version.
  2. Played around with the aws-sdk/client-ses version.
  3. I researched the internet for possible answers and found none that were helpful.
  4. Install the "tslib" library manually in the layer's folder.
Orjwan98
  • 11
  • 2

0 Answers0