Skip to content

Node.js Lambda streaming, await after response stream error

0

I want to capture and send errors that happen on the response stream of a streamified Node.js Lambda handler, similar to this:

export const handler = awslambda.streamifyHandler(
  async (context, responseStream, event) => {
    responseStream.on('error', async (error) => {
      await sendError(error);
    }

    responseStream.destroy(new Error('destroyed'));
  }
);

However, from the logs it looks like while I'm entering the error callback correctly, the runtime does not await any async work after the stream has errored, and instead exits the process immediately. Can you confirm that this is the expected behavior, and if yes, if there is maybe some other way I could achieve this?

asked a year ago190 views

1 Answer
0

Yes, this is the expected behavior. When using response streaming in Lambda, the runtime does not wait for asynchronous work to complete after the response stream has errored or been destroyed.

For handling errors in a streaming Lambda function, there are a few approaches you can consider:

  1. Use error trailers: For errors that occur after you've started writing the response, you can attach HTTP trailing headers named Lambda-Runtime-Function-Error-Type and Lambda-Runtime-Function-Error-Body. Lambda will treat this as a successful response but forward the error metadata to the client.

  2. Report errors before streaming begins: Use the /runtime/invocation/AwsRequestId/error endpoint to report function or runtime errors to Lambda. However, this can only be called before you begin sending an invocation response.

  3. Alternative approach using response streaming pattern: Instead of trying to handle errors after the stream is destroyed, you can use the response streaming capability to return a response to the client first, and then perform your error handling work:

export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
try {
// Return response to client
responseStream.setContentType('application/json');
responseStream.write(JSON.stringify({status: "processing"}));
responseStream.end();

// Now handle the error case
await sendError(new Error('Something went wrong'));
} catch (error) {
// Handle any errors in the error handling itself
console.error("Failed to process error:", error);
}
});

This pattern allows you to first send a response to the client, then perform your error handling work afterward. The Lambda function will continue executing until the handler function completes, even after the response has been sent.

Note that when testing your function through the Lambda console, responses will always appear as buffered rather than streamed.
Sources
Building a custom runtime for AWS Lambda - AWS Lambda
Running code after returning a response from an AWS Lambda function | AWS Compute Blog
Response streaming for Lambda functions - AWS Lambda

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.