sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

Sentry.GCPFunction.wrapHttpFunction cause Error [ERR_STREAM_WRITE_AFTER_END]: write after end

Open jiangbo0216 opened this issue 2 years ago • 6 comments
trafficstars

Is there an existing issue for this?

  • [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [X] I have reviewed the documentation https://docs.sentry.io/
  • [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Self-hosted/on-premise

Which SDK are you using?

@sentry/serverless

SDK Version

"@sentry/serverless": "^7.64.0"

Framework Version

No response

Link to Sentry event

No response

SDK Setup

No response

Steps to Reproduce

new a simple google-cloud demo

pnpm i @google-cloud/functions-framework @sentry/serverless

  1. create index.js
const Sentry = require('@sentry/serverless');
Sentry.GCPFunction.init({
    dsn: <your dsn>,
    tracesSampleRate: 1.0,
  });
exports.helloWorld = Sentry.GCPFunction.wrapHttpFunction(async (req, res) => {
    Promise.reject('error');
    res.send('Hello, World');
  });
  1. start function
npx @google-cloud/functions-framework --target=helloWorld

Expected Result

process run and don't exit

Actual Result

link: https://github.com/getsentry/sentry-javascript/issues/2344

get a error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end sentry patch end function, cause res.end turn sync to async

https://github.com/getsentry/sentry-javascript/blob/2d80b4b2cfabb69f0cfd4a96ea637a8cabbd37cb/packages/serverless/src/gcpfunction/http.ts#L105-L118

and @google-cloud/functions-framework depend res.end onfinished to handle error

https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/35533b76face60714a9f6050aaced98da231016b/src/server.ts#L137-L143

https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/35533b76face60714a9f6050aaced98da231016b/src/function_wrappers.ts#L105-L130

const wrapHttpFunction = (execute) => {
    return (req, res) => {
        const d = domain.create();
        const errorHandler = (err) => {
            if (res.locals.functionExecutionFinished) {
                console.error(`Exception from a finished function: ${err}`);
            }
            else {
                res.locals.functionExecutionFinished = true;
                (0, logger_1.sendCrashResponse)({ err, res });
            }
        };
        // Catch unhandled errors originating from this request.
        d.on('error', errorHandler);
        d.run(() => {
            process.nextTick(() => {
                const ret = execute(req, res);
                // Catch rejected promises if the function is async.
                if (ret instanceof Promise) {
                    ret.catch(errorHandler);
                }
            });
        });
    };
};

in this case,

 res.send('Hello, World')

start to end response but it is async

so when a error in user handler,

        d.on('error', errorHandler);

errorHandler will be triggered, and sendCrashResponse will be called, At this point, Error [ERR_STREAM_WRITE_AFTER_END]: write after end may occur

jiangbo0216 avatar Aug 19 '23 01:08 jiangbo0216

Hi @jiangbo0216, thanks for writing in and for opening a PR! We're very busy this week but we'll try to look into this next week. Thanks!

Lms24 avatar Aug 23 '23 08:08 Lms24

hava any update?

Hi @jiangbo0216, thanks for writing in and for opening a PR! We're very busy this week but we'll try to look into this next week. Thanks!

jiangbo0216 avatar Sep 01 '23 07:09 jiangbo0216

What's happening with this issue? We're looking to use Sentry but this issues prevents us from using it in our serverless functions environment

simonnztg avatar Aug 20 '24 02:08 simonnztg

Hey @simonnztg thanks for writing in. We're currently on company-wide hackweek and thus on limited support. We'll take another look at this next week.

andreiborza avatar Aug 20 '24 07:08 andreiborza

Hi, @simonnztg currently we are not working on this issue because bluntly said, the gcpfunction integration doesn't get much use (might be a self-fulfilling prophecy). If you want to use Sentry in your GCP functions, as a workaround, you should be able to just use the @sentry/node package and call Sentry.init() somewhere in the global scope. This will not automatically track the performance of your functions, but you can manually add Sentry.startSpan() calls though.

(Corporate speech off: I low-key want to use GCP functions for my side project so this integration may get some love soon.)

lforst avatar Aug 26 '24 08:08 lforst

Hi, @simonnztg currently we are not working on this issue because bluntly said, the gcpfunction integration doesn't get much use (might be a self-fulfilling prophecy). If you want to use Sentry in your GCP functions, as a workaround, you should be able to just use the @sentry/node package and call Sentry.init() somewhere in the global scope. This will not automatically track the performance of your functions, but you can manually add Sentry.startSpan() calls though.

(Corporate speech off: I low-key want to use GCP functions for my side project so this integration may get some love soon.)

Thanks for getting back to me. I thought this might be the case, and I have a workaround in place so we can keep using it for now. FWIW, functions support was one of the main things that attracted me to Sentry.

techfoundrynz avatar Aug 26 '24 08:08 techfoundrynz

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you remove the label Waiting for: Community, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

getsantry[bot] avatar Jan 01 '25 08:01 getsantry[bot]