Unexpected Errors in Lambda Functions
Previously, we looked at how to debug errors in our Lambda function code. In this chapter let’s look at how to debug some unexpected errors. Starting with the case of a Lambda function timing out.
Debugging Lambda Timeouts
Our Lambda functions often make API requests to interact with other services. In our notes app, we talk to DynamoDB to store and fetch data; and we also talk to Stripe to process payments. When we make an API request, there is the chance the HTTP connection times out or the remote service takes too long to respond. We are going to look at how to detect and debug the issue. The default timeout for Lambda functions are 6 seconds. So let’s simulate a timeout using setTimeout
.
Replace the main
function in packages/functions/src/get.ts
with the following.
export const main = handler(async (event: APIGatewayProxyEvent) => {
let path_id
if (!event.pathParameters || !event.pathParameters.id || event.pathParameters.id.length == 0) {
throw new Error("Please provide the 'id' parameter.");
} else {
path_id = event.pathParameters.id
}
const params = {
TableName: Table.Notes.tableName,
// 'Key' defines the partition key and sort key of
// the item to be retrieved
Key: {
userId: event.requestContext.authorizer?.iam.cognitoIdentity.identityId,
noteId: path_id, // The id of the note from the path
},
};
const result = await dynamoDb.get(params);
if (!result.Item) {
throw new Error("Item not found.");
}
// Set a timeout
await new Promise((resolve) => setTimeout(resolve, 10000));
// Return the retrieved item
return result.Item;
});
Let’s commit this code.
$ git add .
$ git commit -m "Adding a timeout"
$ git push
Head over to your Seed dashboard, select the prod stage in the pipeline and deploy the debug
branch.
On your notes app, try and select a note. You will notice the page tries to load for a couple of seconds, and then fails with an error alert.
You’ll get an error alert in Sentry. And if you head over to the Issues tab in Seed you’ll notice a new error — Lambda Timeout Error
.
If you click on the new error, you’ll notice that the request took 6006.18ms. And since the Lambda timeout is 6 seconds by default. This means that the function timed out.
To drill into this issue further, add a console.log
in your Lambda function. This messages will show in the request log and it’ll give you a sense of where the timeout is taking place.
Next let’s look at what happens when our Lambda function runs out of memory.
Debugging Out of Memory Errors
By default, a Lambda function has 1024MB of memory. You can assign any amount of memory between 128MB and 3008MB in 64MB increments. So in our code, let’s try and allocate more memory till it runs out of memory.
Replace the main
function in packages/functions/src/get.ts
with the following.
function allocMem():Array<number> {
let bigList: Array<number> = Array(4096000).fill(1);
return bigList.concat(allocMem());
}
export const main = handler(async (event: APIGatewayProxyEvent) => {
let path_id
if (!event.pathParameters || !event.pathParameters.id || event.pathParameters.id.length == 0) {
throw new Error("Please provide the 'id' parameter.");
} else {
path_id = event.pathParameters.id
}
const params = {
TableName: Table.Notes.tableName,
// 'Key' defines the partition key and sort key of
// the item to be retrieved
Key: {
userId: event.requestContext.authorizer?.iam.cognitoIdentity.identityId,
noteId: path_id, // The id of the note from the path
},
};
const result = await dynamoDb.get(params);
if (!result.Item) {
throw new Error("Item not found.");
}
allocMem();
// Return the retrieved item
return result.Item;
});
Now we’ll set our Lambda function to use the lowest memory allowed.
Add the following below the defaults: {
line in your stacks/ApiStack.ts
.
memorySize: 128,
Let’s commit this.
$ git add .
$ git commit -m "Adding a memory error"
$ git push
Head over to your Seed dashboard and deploy it. Then, in your notes app, try and load a note. It should fail with an error alert.
Just as before, you’ll see the error in Sentry. And head over to new issue in Seed.
![Memory error details in Seed]
(/assets/monitor-debug-errors/memory-error-details-in-seed.png)
Note the request took all of 128MB of memory. Click to expand the request.
You’ll see exited with error: signal: killed Runtime.ExitError
. This is printed out by Lambda runtime indicating the runtime was killed. This means that you should give your function more memory or that your code is leaking memory.
Next, we’ll look at how to debug errors that happen outside your Lambda function handler code.
For help and discussion
Comments on this chapter