Skip to content

Sentry.wrapHandler breaks streaming Lambda handlers #12815

Closed as duplicate
Closed as duplicate

Description

@zmillman

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/aws-serverless

SDK Version

8.15.0

Framework Version

No response

Link to Sentry event

No response

SDK Setup/Reproduction Example

Sentry.init({ dsn: process.env.SENTRY_DSN });

Steps to Reproduce

  1. Define an AWS Lambda running with the Node 20.x runtime & configure the SENTRY_DSN env variable:
import * as Sentry from "@sentry/aws-serverless";

Sentry.init({ dsn: process.env.SENTRY_DSN });

// awslambda.streamifyResponse is patched into the global object by the lambda runtime
// https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html
export const handler = Sentry.wrapHandler(
  awslambda.streamifyResponse(async function (event, responseStream, _context) {

    responseStream.write("hello");
    responseStream.end();
  })
);
  1. Make a request (any payload)
  2. Check Lambda logs for error

Expected Result

Code should execute identically as if there had been no Sentry.wrapHandler (returning "hello")

Actual Result

Error logs from code above:

2024-07-09T00:38:31.701Z	a203c0fb-7d33-4a3f-b5af-f76ed67423e6	ERROR	Invoke Error 	
{
    "errorType": "TypeError",
    "errorMessage": "responseStream.write is not a function",
    "stack": [
        "TypeError: responseStream.write is not a function",
        "    at file:///var/task/index.js:299031:20",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
        "    at async processResult (file:///var/task/index.js:10:14)"
    ]
}

My guess is that wrapHandler wasn't written to detect the streaming Lambda handler which takes different arguments than the default handler.

The Sentry docs have this snippet:

exports.handler = Sentry.wrapHandler(async (event, context) => {
  // Your handler code
});

...but the AWS streaming handler expects the second argument to be responseStream (not context)

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jul 9, 2024
  2. chargome commented on Jul 9, 2024

    @chargome
    Member

    Hey @zmillman, thanks for reaching out. Currently our wrapHandler function does not support streamifyResponse. If you still want to use wrapHandler make sure you pass a function that takes the correct arguments.

    We will put this issue onto our backlog to support streamifyResponse.

  3. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jul 9, 2024
  4. JQuezada0 commented on Jul 24, 2024

    @JQuezada0

    Ran into this as well, although the error message was different

    underlyingStream.setContentType is not a function
    

    Here's an example workaround that worked for me.

    export const handler = awslambda.streamifyResponse(
      async function (event, responseStream, context) {
        const sentryHandler = SentryServerless.wrapHandler(async function () {
          return sstHandlerModule.handler(event, responseStream, context);
        });
    
        return sentryHandler(event, context, () => undefined);
      },
    );

    You can "trick" the wrapHandler function and then pass the actual 3 arguments needed for streaming inside.

  5. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jul 24, 2024
  6. Lms24 commented on Jul 25, 2024

    @Lms24
    Member

    Hey @JQuezada0 thanks for posting this workaround. For the time being, this is how we recommend using the wrapper with streamifyResponse.

    Note: If anyone coming across this issue is using our AWS Lambda layer and relied on its auto-wrapping capabilities, I suggest switching to the alternative layer usage which gives you the freedom to apply our wrapper yourself as shown in the code snippet above.

  7. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jul 25, 2024
  8. heypiotr commented on Mar 18, 2025

    @heypiotr

    Just a friendly nudge, New Relic beat you to it 😉 newrelic/node-newrelic#2901

  9. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Mar 18, 2025
  10. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Mar 18, 2025
  11. chargome commented on Mar 18, 2025

    @chargome
    Member

    @andreiborza can I put this on your radar 👀

  12. self-assigned this
    on Mar 19, 2025
  13. andreiborza commented on Mar 21, 2025

    @andreiborza
    Member

    I created a tracking issue for this: #15774. Please follow that issue for updates, I will close this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions