getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.85k stars 1.55k forks source link

Cannot read property 'finish' of undefined #2984

Closed felipedumer closed 3 years ago

felipedumer commented 3 years ago

Version:

5.26.0

Description

0

Good afternoon,

After new release: The sentry service works, But I'm getting this message in Amazon CloudWatch:

ERROR   Invoke Error    
{
    "errorType": "TypeError",
    "errorMessage": "Cannot read property 'finish' of undefined",
    "stack": [
        "TypeError: Cannot read property 'finish' of undefined",
        "    at Runtime.eval [as handler] (webpack://rpc-analise-input/./node_modules/@sentry/serverless/esm/awslambda.js?:216:25)",
        "    at processTicksAndRejections (internal/process/task_queues.js:97:5)"
    ]
}

Sentry common file

import * as sentry from '@sentry/serverless';

sentry.AWSLambda.init({dsn: 'https://somedsn',
});

export default sentry;

Lambda file

import sentry from '../common/sentry';

const handler = async (event) => {}

exports.handler = sentry.AWSLambda.wrapHandler(handler);

Error location

const transaction = startTransaction({
            name: context.functionName,
            op: 'awslambda.handler',
        });

Line 170: transaction.finish();
pradel commented 3 years ago

I have the same issue with "5.26.0" of "@sentry/serverless", I have to use "5.25.0" for now.

p0wl commented 3 years ago

We have the same issue with 5.26.0, but not with 5.25.0.

I tried to create a test to show it, but could not reproduce it in a test case.

qtiki commented 3 years ago

I am in the process of switching from our old @sentry/node based AWS Lambda wrapper with custom flushing to the official @sentry/serverless package. I ran into this issue with 5.27.1 and just like everyone else downgrading to 5.25.0 fixed it. So I guess I'll stick to that version for the foreseeable future.

Not really related to this issue, but I noticed that the package does not have all TypeScript dependencies set properly so adding the package caused compilation to break until I manually added @google-cloud/functions-framework and @types/express packages.

qtiki commented 3 years ago

Just to give more details: I saw this when using serverless-offline to run the Lambda offline without calling AWSLambda.init. I didn't test if it would have worked inside AWS with the init because I want the offline handler code to be the same as the online handler.

cranberyxl commented 3 years ago

Try adding import '@sentry/tracing';where in you call startTransaction

skinofstars commented 3 years ago

Downgrading to 5.25.0 is resulting in o.init is not a function... however, I found you need to change to Sentry.init({... in versions prior to 5.26.0

asermax commented 3 years ago

After doing some digging, I found that the AWSLambda's handler wrapper makes use of the startTransaction method, which is dynamically registered by @sentry/tracing as an "extension" of Sentry's core functionality. My guess is that either the docs are missing a step to correctly import and enable this extension or webpack's tree-shaking (in my case at least) is discarding the tracing code since it's not used directly but only through the extension mechanism.

In any case, I was able to get this working without the error by adding the following before the init call:

import * as SentryTracing from '@sentry/tracing';
SentryTracing.addExtensionMethods();
bscaspar commented 3 years ago

I am also experiencing this with "@sentry/serverless": "^5.27.4", the workaround mentioned by @asermax fixed it, ty!

piotrblasiak commented 3 years ago

Any update on this? Pretty old issue and rather serious to not be able to use this lib in its most basic use case according to the manual (without a hack).

marshall-lee commented 3 years ago

Yeah it seems to be related to webpack tree-shaking feature or something else webpack-related.

Could you please provide a webpack configuration that reproduces the issue? Knowing the webpack version and the versions of plugins will be helpful too.

Some time ago I experimented with webpack + sentry on aws lambda and everything worked fine so I definitely miss the point how it could be broken.

p0wl commented 3 years ago

We have seen the issue but don't use webpack at all. We are using typescript for the lambda functions but no bundler.

marshall-lee commented 3 years ago

@p0wl

what build configuration do you use?

p0wl commented 3 years ago

we are deploying using aws-cdk, which zips a folder and uploads it as lambda asset. Our typescript config is the aws-cdk standard.

tsconfig:

{
  "compilerOptions": {
    "target": "ES2018",
    "module": "commonjs",
    "lib": [
      "es2018"
    ],
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "exclude": [
    "cdk.out"
  ]
}

and here is the change how we tried to switch from serverless-sentry-lib to @sentry/serverless:

--- a/resources/lambda-base/lib/withSentry.ts
+++ b/resources/lambda-base/lib/withSentry.ts
@@ -1,4 +1,14 @@
-const withSentry = require('serverless-sentry-lib').default;
+import * as Sentry from '@sentry/serverless';

+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+const withSentry: (handler: any, handlerOptions?: any | undefined) => any =
+  Sentry.AWSLambda.wrapHandler;
+
+Sentry.init({
+  dsn: process.env.SENTRY_DSN,
+});
+
+export { Sentry };
 export default withSentry;
jdrydn commented 3 years ago

Can confirm this issue also happens with regular Webpack builds, currently on @sentry/serverless@5.29.0, using serverless@2.15.0, serverless-webpack@5.3.5, webpack@4.44.2 & the following webpack.config.js:

const slsw = require('serverless-webpack');
const webpack = require('webpack');

const { stage } = slsw.lib.serverless.service.provider;
const { isLocal } = slsw.lib.webpack;

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  context: process.env.PWD,
  // Disable verbose logs
  stats: stage === 'prod' ? 'errors-only' : 'normal',
  devtool: 'source-map',
  externals: [ 'aws-sdk' ],
  mode: isLocal ? 'development' : 'production',
  performance: {
    hints: false,
  },
  node: {
    __dirname: false,
  },
  resolve: {
    symlinks: false,
  },
  optimization: isLocal
    ? { splitChunks: false, removeEmptyChunks: false, removeAvailableModules: false }
    : { minimize: false },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(stage === 'prod' ? 'production' : 'development'),
      'process.env.WEBPACK_ENV': JSON.stringify('WEBPACK'),
    }),
  ],
};

Producing a HTTP 502 Bad Gateway with API-Gateway, and the following log in Cloudwatch:

{
    "errorType": "TypeError",
    "errorMessage": "Cannot read property 'finish' of undefined",
    "stack": [
        "TypeError: Cannot read property 'finish' of undefined",
        "    at Runtime.handler (/var/task/index.js:23207:25)"
    ]
}

Can confirm @asermax's fix appears to resolve this issue, my guess is adding SentryTracing.addExtensionMethods() stops Webpack from stripping out "unnecessary" dependencies:

const Sentry = require('@sentry/serverless');
const SentryTracing = require('@sentry/tracing');

SentryTracing.addExtensionMethods();
Sentry.AWSLambda.init({
  // dsn: process.env.SENTRY_DSN, // Populated by env var
  tracesSampleRate: 1.0,
});
vvo commented 3 years ago

This happens with various bundlers (CDK uses esbuild, I use webpack).

You can solve this, for now, this way:

If you're using CDK, here's how to add sentry as a layer:

new NodejsFunction(this, "test", {
 layers: [lambda.LayerVersion.fromLayerVersionArn(
   this,
   "sentry-serverless",
   "arn:aws:lambda:us-east-1:943013980633:layer:SentryNodeServerlessSDK:6", // example arn for iad-1, use https://docs.sentry.io/platforms/node/guides/aws-lambda/layer/ to find the right one
 )]
});

PS: Also make sure to use import * as sentry from '@sentry/serverless'; and not import Sentry from '@sentry/serverless'; if you're using ES6 imports. Otherwise it fails.

p0wl commented 3 years ago

Awesome!! I was waiting for Sentry being available as a layer! Just out of curiosity, how did you find the layer? Is there a github issue or something where this was tracked?

vvo commented 3 years ago

I just read their docs and found there was a link to the layer. I guess it has been added recently maybe? seen here:

image

https://docs.sentry.io/platforms/node/guides/aws-lambda/

aldegoeij commented 3 years ago

any chance this is solved yet in a next release? Or is the go to solution to use the layer (which kinda sucks from a versioning standpoint)?

mkrcah commented 3 years ago

For @sentry/serverless": "6.2.3", with Typescript & Webpack, this worked for me:

const Sentry = require('@sentry/serverless')
const SentryTracing = require('@sentry/tracing')
SentryTracing.addExtensionMethods()
Sentry.AWSLambda.init({...})
Trinovantes commented 3 years ago

Tracing.addExtensionMethods() is the key fix since that's the side effect of calling import * as Tracing from '@sentry/tracing' https://github.com/getsentry/sentry-javascript/blob/eb756d2be6a4058049973d9d737eb2309a096bbf/packages/tracing/src/index.ts#L20-L21

This package incorrect marked the source file index.ts rather than what actually gets imported by webpack "module": "esm/index.js" as a side effect https://github.com/getsentry/sentry-javascript/blob/eb756d2be6a4058049973d9d737eb2309a096bbf/packages/tracing/package.json#L88-L90

matthew119427 commented 2 years ago

This is happening to me without using serverless, just the regular Node.js package using TS.

sunderee commented 2 years ago

Try adding import '@sentry/tracing';where in you call startTransaction

This helped me a lot. Thanks!

gothraven commented 1 year ago

I'm having this error in "@sentry/serverless": "7.47.0"

{
    "errorType": "TypeError",
    "errorMessage": "Cannot read properties of undefined (reading 'finish')",
    "stack": [
        "TypeError: Cannot read properties of undefined (reading 'finish')",
        "    at Runtime.handler (/var/task/node_modules/@sentry/serverless/cjs/awslambda.js:298:19)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
    ]
}

I'm using the AWS lambda Partial failures response

{ 
  "batchItemFailures": [ 
    {
      "itemIdentifier": "<id>"
    },
    {
      "itemIdentifier": "<id>"
    }
  ]
}