Hey, there!
Today I spent a good few hours trying to solve a problem on AWS Lambda and given how deep the problem was, I thought it would be a good idea to share the solution.
✏️ The Context
I am using Jovo Framework to develop a voice app for both Alexa and Google Assistant and one of their guides teach how to deploy the code to an AWS Lambda function using serverless CLI.
🛑 The Problem
After setting everything up and having the code deployed successfully, when trying to run the lambda function the following error was popping up in the cloud logs
{
"errorType": "TypeError",
"errorMessage": "Cannot redefine property: handler",
"trace": [
"TypeError: Cannot redefine property: handler",
" at Function.defineProperty (<anonymous>)",
" at defineProperty (/opt/otel-extension/node_modules/shimmer/index.js:14:10)",
" at AwsLambdaInstrumentation.wrap [as _wrap] (/opt/otel-extension/node_modules/shimmer/index.js:56:3)",
" at InstrumentationNodeModuleFile.patch (/opt/otel-extension/node_modules/@opentelemetry/instrumentation-aws-lambda/src/instrumentation.ts:124:20)",
" at AwsLambdaInstrumentation._onRequire (/opt/otel-extension/node_modules/@opentelemetry/instrumentation/src/platform/node/instrumentation.ts:109:23)",
" at /opt/otel-extension/node_modules/@opentelemetry/instrumentation/src/platform/node/instrumentation.ts:143:25",
" at Module.Hook._require.Module.require (/opt/otel-extension/node_modules/require-in-the-middle/index.js:154:32)",
" at Module.Hook._require.Module.require (/opt/otel-extension/node_modules/require-in-the-middle/index.js:80:39)",
" at Module.Hook._require.Module.require (/opt/otel-extension/node_modules/require-in-the-middle/index.js:80:39)",
" at Module.Hook._require.Module.require (/opt/otel-extension/node_modules/require-in-the-middle/index.js:80:39)"
]
}
Note: in the image above the error shows as "Cannot redefine property: myHandler" because I've changed the function name for debugging purposes.
The easiest way to reproduce the error was using the Test feature from AWS Lambda with an Alexa Start Session template.
🤕 The culprit
It took me a while to notice that, according to the stack trace, the error was happening in a dependency of otel-extension
: shimmer
at defineProperty (/opt/otel-extension/node_modules/shimmer/index.js:14:10)
Shimmer is a monkeypatching library that a telemetry extension for AWS Lambda was using.
According to this issue, the problem is using esbuild bundle generator - that Jovo uses - with this telemetry extension.
The responsible for actually adding this telemetry extensions as an AWS Lambda layer was serverless cli.
🔧 The solution
As suggested in both opentelemetry-js-contrib and aws-otel-lambda issues, the solution is changing ES6 export
to CommonJS module.exports
.
Instead of
export const handler = () => {
// removed for brevity
};
Do this
const handler = () => {
// removed for brevity
};
module.exports = { handler }
But, since I'm using Jovo with AWS Lambda, I actually had to change the app.prod.ts
file (where prod
can be other stage name you defined while running jovo new:stage <stage>
).
// app.prod.ts
import { app } from './app'
import { handler } from './server.lambda'
app.configure({
//...
})
module.exports = { handler }
🙏 The Conclusion
I was sure that I was doing something wrong in some configuration step, since this setup involves several services: Jovo, Serveless, AWS Lambda and AWS API Gateway.
It was kinda relieving to know that the problem was actually a compatibility issue between esbuild and open-telemetry.
Nonetheless, I was able to learn a lot about these services as usual with any deep debugging problem we have to deal as developers.
Top comments (0)