I am using the Serverless Framework with the serverless-webpack
plugin, Prisma, and Node 12.x on AWS. I have several lambdas that each execute some async code, but some of the code doesn't seem to execute (or promises fulfill). The code works perfectly locally, but not when deployed on AWS.
Example lambda with relevant comments inline:
"use strict";
import { PrismaClient } from "@prisma/client";
import fetch from "node-fetch";
const prisma = new PrismaClient();
module.exports.handler = async (event, context, callback) => {
try {
const users = await prisma.user.findMany();
console.log(`Users: ${JSON.stringify(users)}`); // shows properly in Lambda logs
users.map(async (user) => {
const res = await fetch(`...`); // doesn't seem to execute on AWS but does locally
const data = await res.json();
const query = await prisma.user.update({...}); // doesn't seem to execute on AWS but does locally
console.log(data); // doesn't show up in Lambda logs
console.log(query); //doesn't show up in Lambda logs
});
// shows properly in Lambda logs
console.log(
`Completed ${context.functionName} at ${new Date().toLocaleString()}`
);
} catch (err) {
console.log(`ERROR: ${context.functionName} failed with error ${err}`);
}
};
webpack.config.js
:
const path = require("path");
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
context: __dirname,
mode: slsw.lib.webpack.isLocal ? "development" : "production",
entry: slsw.lib.entries,
devtool: slsw.lib.webpack.isLocal
? "cheap-module-eval-source-map"
: "source-map",
resolve: {
extensions: [".mjs", ".json", ".ts"],
symlinks: false,
cacheWithContext: false,
},
output: {
libraryTarget: "commonjs",
path: path.join(__dirname, ".webpack"),
filename: "[name].js",
},
target: "node",
externals: [nodeExternals()],
module: {
rules: [
// all files with `.ts` or `.tsx` extension handled by `ts-loader`
{
test: /\.(tsx?)$/,
loader: "ts-loader",
exclude: [
[
path.resolve(__dirname, "node_modules"),
path.resolve(__dirname, ".serverless"),
path.resolve(__dirname, ".webpack"),
],
],
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
},
],
},
plugins: [
new CopyWebpackPlugin({ patterns: ["prisma/schema.prisma"] }),
],
};
I have also tried without the try/catch block, and have increased the lambda timeout in serverless.yml
. I thought maybe it had to do with the nested async (user.map(async ...)
), but I am not sure. The CloudWatch logs for the lambdas show no errors, and only show the console.log()
s outside of the map function as indicated in the code. Any help is greatly appreciated. Thank you so much!
EDIT: I am now receiving an error in the CloudWatch logs: ERROR: [LAMBDA_NAME] failed with error FetchError: request to [ENDPOINT] failed, reason: connect ETIMEDOUT [IP_ADDRESS]:443.
I think this is a separate issue, however. The solution was to change users.map(async (user) => {...}
to for (const user of users) {...}
as @CyberEternal suggested.
The issue related to the async function in the map. Actually, it's not working. You can try the "for" loop. It's working 100%.
Try this way
And it will be better if you use a separate function for the update process. Like this way