Skip to content

Commit

Permalink
ref(serverless): Added ignoreSentryErrors option for AWS lambda (#4620)
Browse files Browse the repository at this point in the history
Add option to ignore internal `SentryError` errors, such as those that come from 429 or 413 responses.
  • Loading branch information
ichina committed Feb 23, 2022
1 parent 86a526a commit 22a7cf3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
12 changes: 10 additions & 2 deletions packages/serverless/src/awslambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '@sentry/node';
import { extractTraceparentData } from '@sentry/tracing';
import { Integration } from '@sentry/types';
import { isString, logger } from '@sentry/utils';
import { isString, logger, SentryError } from '@sentry/utils';
// NOTE: I have no idea how to fix this right now, and don't want to waste more time, as it builds just fine — Kamil
// eslint-disable-next-line import/no-unresolved
import { Context, Handler } from 'aws-lambda';
Expand Down Expand Up @@ -53,6 +53,7 @@ export interface WrapperOptions {
* @default false
*/
captureAllSettledReasons: boolean;
ignoreSentryErrors: boolean;
}

export const defaultIntegrations: Integration[] = [...Sentry.defaultIntegrations, new AWSServices({ optional: true })];
Expand Down Expand Up @@ -224,6 +225,7 @@ export function wrapHandler<TEvent, TResult>(
captureTimeoutWarning: true,
timeoutWarningLimit: 500,
captureAllSettledReasons: false,
ignoreSentryErrors: false,
...wrapOptions,
};
let timeoutWarningTimer: NodeJS.Timeout;
Expand Down Expand Up @@ -314,7 +316,13 @@ export function wrapHandler<TEvent, TResult>(
clearTimeout(timeoutWarningTimer);
transaction.finish();
hub.popScope();
await flush(options.flushTimeout);
await flush(options.flushTimeout).catch(e => {
if (options.ignoreSentryErrors && e instanceof SentryError) {
logger.error(e);
return;
}
throw e;
});
}
return rv;
};
Expand Down
39 changes: 39 additions & 0 deletions packages/serverless/test/awslambda.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SentryError } from '@sentry/utils';
// NOTE: I have no idea how to fix this right now, and don't want to waste more time, as it builds just fine — Kamil
// eslint-disable-next-line import/no-unresolved
import { Callback, Handler } from 'aws-lambda';
Expand Down Expand Up @@ -177,6 +178,44 @@ describe('AWSLambda', () => {
expect(Sentry.captureException).toHaveBeenNthCalledWith(2, error2);
expect(Sentry.captureException).toBeCalledTimes(2);
});

test('ignoreSentryErrors - with successful handler', async () => {
const sentryError = new SentryError('HTTP Error (429)');
jest.spyOn(Sentry, 'flush').mockRejectedValueOnce(sentryError);

const handledError = new Error('handled error, and we want to monitor it');
const expectedSuccessStatus = { status: 'success', reason: 'we handled error, so success' };
const handler = () => {
Sentry.captureException(handledError);
return Promise.resolve(expectedSuccessStatus);
};
const wrappedHandlerWithoutIgnoringSentryErrors = wrapHandler(handler, { ignoreSentryErrors: false });
const wrappedHandlerWithIgnoringSentryErrors = wrapHandler(handler, { ignoreSentryErrors: true });

await expect(wrappedHandlerWithoutIgnoringSentryErrors(fakeEvent, fakeContext, fakeCallback)).rejects.toThrow(
sentryError,
);
await expect(wrappedHandlerWithIgnoringSentryErrors(fakeEvent, fakeContext, fakeCallback)).resolves.toBe(
expectedSuccessStatus,
);
});

test('ignoreSentryErrors - with failed handler', async () => {
const sentryError = new SentryError('HTTP Error (429)');
jest.spyOn(Sentry, 'flush').mockRejectedValueOnce(sentryError);

const criticalUnhandledError = new Error('critical unhandled error ');
const handler = () => Promise.reject(criticalUnhandledError);
const wrappedHandlerWithoutIgnoringSentryErrors = wrapHandler(handler, { ignoreSentryErrors: false });
const wrappedHandlerWithIgnoringSentryErrors = wrapHandler(handler, { ignoreSentryErrors: true });

await expect(wrappedHandlerWithoutIgnoringSentryErrors(fakeEvent, fakeContext, fakeCallback)).rejects.toThrow(
sentryError,
);
await expect(wrappedHandlerWithIgnoringSentryErrors(fakeEvent, fakeContext, fakeCallback)).rejects.toThrow(
criticalUnhandledError,
);
});
});

describe('wrapHandler() on sync handler', () => {
Expand Down

0 comments on commit 22a7cf3

Please sign in to comment.