arabold / serverless-sentry-lib

MIT License
32 stars 15 forks source link

Capturing "extra" automatically #22

Closed jamaica474 closed 4 years ago

jamaica474 commented 4 years ago

When I used serverless-sentry-lib v1 I got used to providing additional parameters to exception which were sent to sentry automatically( new Exception('Message', { additionalInfo })

This logic doesn't seem to work by default in v2

arabold commented 4 years ago

Thanks for your bug report. I've looked through the code but I'm unable to identify any obvious differences. When an unhandled exception is thrown or the Lambda returns an error object, the library will simply call

sentryClient.captureException(err);

No special handling in unwrapping (i.e. something like JSON.stringify) the error object is done in serverless-sentry-lib itself but it's left up to Sentry to handle this as usual. Please try calling sentryClient.captureException(err); yourself manually and see whether Sentry reports it differently this time.

The only notable difference to v1 is that the lib now captures unhandled Promise rejections differently than before. But even in that case the original error object is passed as payload and unwrapping should be handled by Sentry.

jamaica474 commented 4 years ago

When I'm calling captureException with no second argument behavior is identical to sentry-lib.

This is how I'm calling it now.

captureMessage(msg, { extra: 'additional string or object', });

Before update I had no need to provide that "extra" key, sentry was capturing everything in "extra" by default. Not sure where that happened thou

jamaica474 commented 4 years ago

In the end I'm getting those exceptions twice - first time by "captureException", and then on the top level. First one has extras, second one does not. Very confusing.

arabold commented 4 years ago

I have no real explanation for this other than to check if and how you're using Sentry's scopes. The lib is not overwriting or changing any existing Sentry functionality and shouldn't impact the behavior of Sentry itself in any way.

Typically the captureMessage are wrapped in a withScope call like this:

sentryClient.withScope((scope) => {
  scope.setExtras({ ... });
  sentryClient.captureMessage('Hello World');
});

Or to configure the current scope instead of creating a new subscope like above:

sentryClient.configureScope((scope) => {
  scope.setExtras({ ... });
});

// ...sometime later...
sentryClient.withScope((scope) => {
  sentryClient.captureMessage('Hello World');
});

serverless-sentry-lib is using configureScope at the initial invocation of the Lambda to set some global context variables. In case it is generating warnings or errors it uses withScope.

jamaica474 commented 4 years ago

Here's what I ended up doing. Just in case someone having similar difficulties


    Sentry.init({
      dsn: process.env.SENTRY_DSN,
      debug: true,

      beforeSend: (event, hint) => {
        const log = getLogger('sentry-before-send');
        const { originalException } = hint;
        log('Original exception: %o', originalException);

        const extra =
          originalException instanceof Exception && originalException.extra;

        log('Extra: %o', extra);
        if (extra) {
          log('Adding extras to event');
          event.extra = extra;
        }

        return event;
      },
    });```