diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless/src/lambda-functions-layer/ExperimentalExtension/index.mjs b/dev-packages/e2e-tests/test-applications/aws-serverless/src/lambda-functions-layer/ExperimentalExtension/index.mjs deleted file mode 100644 index d4cd56b78c90..000000000000 --- a/dev-packages/e2e-tests/test-applications/aws-serverless/src/lambda-functions-layer/ExperimentalExtension/index.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import * as Sentry from '@sentry/aws-serverless'; - -Sentry.init({ - dsn: process.env.SENTRY_DSN, - tracesSampleRate: 1, - debug: true, - _experiments: { - enableLambdaExtension: true, - }, -}); - -export const handler = async (event, context) => { - Sentry.startSpan({ name: 'manual-span', op: 'test' }, async () => { - return 'Hello, world!'; - }); -}; diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/layer.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/layer.test.ts index 6ec76124140d..bb7ae03a96e7 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/layer.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/layer.test.ts @@ -242,52 +242,4 @@ test.describe('Lambda layer', () => { }), ); }); - - test('experimental extension works', async ({ lambdaClient }) => { - const transactionEventPromise = waitForTransaction('aws-serverless-lambda-sam', transactionEvent => { - return transactionEvent?.transaction === 'LayerExperimentalExtension'; - }); - - await lambdaClient.send( - new InvokeCommand({ - FunctionName: 'LayerExperimentalExtension', - Payload: JSON.stringify({}), - }), - ); - - const transactionEvent = await transactionEventPromise; - - expect(transactionEvent.transaction).toEqual('LayerExperimentalExtension'); - expect(transactionEvent.contexts?.trace).toEqual({ - data: { - 'sentry.sample_rate': 1, - 'sentry.source': 'custom', - 'sentry.origin': 'auto.otel.aws-lambda', - 'sentry.op': 'function.aws.lambda', - 'cloud.account.id': '012345678912', - 'faas.execution': expect.any(String), - 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:LayerExperimentalExtension', - 'faas.coldstart': true, - 'otel.kind': 'SERVER', - }, - op: 'function.aws.lambda', - origin: 'auto.otel.aws-lambda', - span_id: expect.stringMatching(/[a-f0-9]{16}/), - status: 'ok', - trace_id: expect.stringMatching(/[a-f0-9]{32}/), - }); - - expect(transactionEvent.spans).toHaveLength(1); - - expect(transactionEvent.spans).toContainEqual( - expect.objectContaining({ - data: expect.objectContaining({ - 'sentry.op': 'test', - 'sentry.origin': 'manual', - }), - description: 'manual-span', - op: 'test', - }), - ); - }); }); diff --git a/packages/aws-serverless/src/init.ts b/packages/aws-serverless/src/init.ts index 9de744bedf34..6640db8ec5fa 100644 --- a/packages/aws-serverless/src/init.ts +++ b/packages/aws-serverless/src/init.ts @@ -15,12 +15,10 @@ export function getDefaultIntegrations(_options: Options): Integration[] { } export interface AwsServerlessOptions extends NodeOptions { - _experiments?: NodeOptions['_experiments'] & { - /** - * If proxying Sentry events through the Sentry Lambda extension should be enabled. - */ - enableLambdaExtension?: boolean; - }; + /** + * If Sentry events should be proxied through the Lambda extension when using the Lambda layer. Defaults to `true` when using the Lambda layer. + */ + useLayerExtension?: boolean; } /** @@ -29,14 +27,14 @@ export interface AwsServerlessOptions extends NodeOptions { * @param options Configuration options for the SDK, @see {@link AWSLambdaOptions}. */ export function init(options: AwsServerlessOptions = {}): NodeClient | undefined { + const sdkSource = getSDKSource(); const opts = { defaultIntegrations: getDefaultIntegrations(options), + useLayerExtension: sdkSource === 'aws-lambda-layer' && !options.tunnel, ...options, }; - const sdkSource = getSDKSource(); - - if (opts._experiments?.enableLambdaExtension) { + if (opts.useLayerExtension) { if (sdkSource === 'aws-lambda-layer') { if (!opts.tunnel) { DEBUG_BUILD && debug.log('Proxying Sentry events through the Sentry Lambda extension'); diff --git a/packages/aws-serverless/test/init.test.ts b/packages/aws-serverless/test/init.test.ts index b4aa7ddc0d2b..576257e3f3e4 100644 --- a/packages/aws-serverless/test/init.test.ts +++ b/packages/aws-serverless/test/init.test.ts @@ -18,14 +18,12 @@ const mockGetSDKSource = vi.mocked(getSDKSource); const mockInitWithoutDefaultIntegrations = vi.mocked(initWithoutDefaultIntegrations); describe('init', () => { - describe('experimental Lambda extension support', () => { + describe('Lambda extension setup', () => { test('should preserve user-provided tunnel option when Lambda extension is enabled', () => { mockGetSDKSource.mockReturnValue('aws-lambda-layer'); const options: AwsServerlessOptions = { tunnel: 'https://custom-tunnel.example.com', - _experiments: { - enableLambdaExtension: true, - }, + useLayerExtension: true, }; init(options); @@ -40,9 +38,7 @@ describe('init', () => { test('should set default tunnel when Lambda extension is enabled and SDK source is aws-lambda-layer', () => { mockGetSDKSource.mockReturnValue('aws-lambda-layer'); const options: AwsServerlessOptions = { - _experiments: { - enableLambdaExtension: true, - }, + useLayerExtension: true, }; init(options); @@ -57,9 +53,7 @@ describe('init', () => { test('should not set tunnel when Lambda extension is disabled', () => { mockGetSDKSource.mockReturnValue('aws-lambda-layer'); const options: AwsServerlessOptions = { - _experiments: { - enableLambdaExtension: false, - }, + useLayerExtension: false, }; init(options); @@ -74,9 +68,7 @@ describe('init', () => { test('should not set tunnel when SDK source is not aws-lambda-layer even with Lambda extension enabled', () => { mockGetSDKSource.mockReturnValue('npm'); const options: AwsServerlessOptions = { - _experiments: { - enableLambdaExtension: true, - }, + useLayerExtension: true, }; init(options); @@ -88,17 +80,52 @@ describe('init', () => { ); }); - test('should not set tunnel when no experiments are provided', () => { + test('should default useLayerExtension to true when SDK source is aws-lambda-layer', () => { mockGetSDKSource.mockReturnValue('aws-lambda-layer'); const options: AwsServerlessOptions = {}; init(options); + expect(mockInitWithoutDefaultIntegrations).toHaveBeenCalledWith( + expect.objectContaining({ + useLayerExtension: true, + tunnel: 'http://localhost:9000/envelope', + }), + ); + }); + + test('should default useLayerExtension to false when SDK source is not aws-lambda-layer', () => { + mockGetSDKSource.mockReturnValue('npm'); + const options: AwsServerlessOptions = {}; + + init(options); + + expect(mockInitWithoutDefaultIntegrations).toHaveBeenCalledWith( + expect.objectContaining({ + useLayerExtension: false, + }), + ); expect(mockInitWithoutDefaultIntegrations).toHaveBeenCalledWith( expect.not.objectContaining({ tunnel: expect.any(String), }), ); }); + + test('should default useLayerExtension to false when tunnel is provided even when SDK source is aws-lambda-layer', () => { + mockGetSDKSource.mockReturnValue('aws-lambda-layer'); + const options: AwsServerlessOptions = { + tunnel: 'https://custom-tunnel.example.com', + }; + + init(options); + + expect(mockInitWithoutDefaultIntegrations).toHaveBeenCalledWith( + expect.objectContaining({ + useLayerExtension: false, + tunnel: 'https://custom-tunnel.example.com', + }), + ); + }); }); });