diff --git a/CHANGELOG.md b/CHANGELOG.md index 2978ea4dba0a..6ccb43b5b6c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,15 @@ Work in this release was contributed by @adityareddy-dev, @jpdefo, @Jxxunnn, @ph `ignoreStaticAssets` defaults to `true`, so workers no longer create spans for `GET` requests to common static assets such as `favicon.ico`, `robots.txt` or `*.js` files. To keep these spans, set `httpServerIntegration({ ignoreStaticAssets: false })`. Request spans also follow the client's tracing configuration by default, so the SDK does not start them when tracing is disabled. If `ignoreRequestBody` throws, the request no longer fails, and the SDK skips the body. +- **feat(node, bun, deno, cloudflare): Align portable exports across server SDKs** + + Node, Bun, Deno and Cloudflare now export the same helpers from `@sentry/core` and `@sentry/server-utils` where they work on that runtime: + + - Node and Bun now export `moduleMetadataIntegration`, `instrumentPostgresJsSql`, `instrumentCreateReactAgent`, `awsIntegration` and the `FlueOptions` type. `awsIntegration` was already in their default integrations. + - Deno and Cloudflare now export `parameterize` and `instrumentStateGraphCompile`. + - Bun and Cloudflare now export the `Log` and `LogSeverityLevel` types. + - Deno now exports `fastifyIntegration`, which was already in its default integrations. + ## 11.8.0 ### Important Changes diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/index.ts b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/index.ts new file mode 100644 index 000000000000..55fb7b4466b8 --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/index.ts @@ -0,0 +1,15 @@ +import * as Sentry from '@sentry/cloudflare'; + +interface Env { + SENTRY_DSN: string; +} + +// A plain worker. The `@sentry/cloudflare/vite` plugin wraps it with `withSentry` at build time, +// with the options from `instrument.server.ts`. +export default { + async fetch(): Promise { + const userId = 42; + Sentry.captureMessage(Sentry.parameterize`User ${userId} logged in`); + return new Response('ok'); + }, +} satisfies ExportedHandler; diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/instrument.server.ts b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/instrument.server.ts new file mode 100644 index 000000000000..9de8aec879bb --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/instrument.server.ts @@ -0,0 +1,5 @@ +import { defineCloudflareOptions } from '@sentry/cloudflare'; + +export default defineCloudflareOptions((env: { SENTRY_DSN: string }) => ({ + dsn: env.SENTRY_DSN, +})); diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/test.ts b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/test.ts new file mode 100644 index 000000000000..b8dc67c3e462 --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/test.ts @@ -0,0 +1,15 @@ +import type { Event } from '@sentry/core'; +import { expect, it } from 'vitest'; +import { createRunner } from '../../../runner'; + +it('parameterize from the public entry sends a message template and its values', async ({ signal }) => { + const runner = createRunner(__dirname) + .expect(envelope => { + const event = envelope[1]?.[0]?.[1] as Event; + expect(event.logentry).toEqual({ message: 'User %s logged in', params: [42] }); + }) + .start(signal); + + await runner.makeRequest('get', '/'); + await runner.completed(); +}); diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/vite.config.mts b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/vite.config.mts new file mode 100644 index 000000000000..005f4448f6cb --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/vite.config.mts @@ -0,0 +1,7 @@ +import { cloudflare } from '@cloudflare/vite-plugin'; +import { sentryCloudflareVitePlugin } from '@sentry/cloudflare/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [cloudflare(), sentryCloudflareVitePlugin()], +}); diff --git a/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/wrangler.jsonc b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/wrangler.jsonc new file mode 100644 index 000000000000..cbfb247dd034 --- /dev/null +++ b/dev-packages/cloudflare-integration-tests/suites/public-api/parameterize/wrangler.jsonc @@ -0,0 +1,9 @@ +{ + "$schema": "../../../node_modules/wrangler/config-schema.json", + "name": "cloudflare-public-api-parameterize", + // `main` points at the source entry. The Sentry Vite plugin builds from it, and the runner serves + // the built output. + "main": "index.ts", + "compatibility_date": "2025-06-17", + "compatibility_flags": ["nodejs_compat"], +} diff --git a/dev-packages/deno-integration-tests/suites/parameterize/test.ts b/dev-packages/deno-integration-tests/suites/parameterize/test.ts new file mode 100644 index 000000000000..16272b3db672 --- /dev/null +++ b/dev-packages/deno-integration-tests/suites/parameterize/test.ts @@ -0,0 +1,25 @@ +// + +import * as Sentry from '@sentry/deno'; +import { assertEquals } from 'https://deno.land/std@0.212.0/assert/assert_equals.ts'; +import { errorSink, resetGlobals, withTimeout } from '../../src/index.ts'; + +Deno.test('parameterize from the public entry sends a message template and its values', async () => { + resetGlobals(); + const sink = errorSink(); + + Sentry.init({ + dsn: 'https://username@domain/123', + beforeSend: sink.beforeSend, + }); + + const userId = 42; + Sentry.captureMessage(Sentry.parameterize`User ${userId} logged in`); + + const event = await withTimeout( + sink.waitFor(e => e.logentry?.message === 'User %s logged in'), + 5_000, + 'parameterized message event', + ); + assertEquals(event.logentry, { message: 'User %s logged in', params: [42] }); +}); diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 80158e311e49..86fd2127c724 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -13,6 +13,7 @@ export { addIntegration, amqplibIntegration, anthropicAIIntegration, + awsIntegration, // eslint-disable-next-line typescript/no-deprecated anrIntegration, googleGenAIIntegration, @@ -102,6 +103,7 @@ export { langChainIntegration, langGraphIntegration, createFlueInstrumentation, + instrumentPostgresJsSql, mastraIntegration, piDurableIntegration, mcpServerIntegration, @@ -177,6 +179,8 @@ export { instrumentLangChainEmbeddings, instrumentStateGraph, instrumentStateGraphCompile, + instrumentCreateReactAgent, + moduleMetadataIntegration, zodErrorsIntegration, profiler, logger, diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts index fd07e76a3fba..994aabb838ce 100644 --- a/packages/aws-serverless/src/index.ts +++ b/packages/aws-serverless/src/index.ts @@ -2,6 +2,7 @@ export { addEventProcessor, addBreadcrumb, addIntegration, + moduleMetadataIntegration, captureException, captureEvent, captureMessage, @@ -71,6 +72,7 @@ export { mcpServerIntegration, SentryMastraExporter, createFlueInstrumentation, + instrumentPostgresJsSql, modulesIntegration, nodeRuntimeMetricsIntegration, type NodeRuntimeMetricsOptions, @@ -159,6 +161,7 @@ export { instrumentGoogleGenAIClient, instrumentStateGraph, instrumentStateGraphCompile, + instrumentCreateReactAgent, zodErrorsIntegration, profiler, amqplibIntegration, diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 4e91068d21f8..f7c8a286287b 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -10,6 +10,8 @@ export type { Exception, Session, SeverityLevel, + Log, + LogSeverityLevel, Span, StackFrame, Stacktrace, @@ -25,6 +27,7 @@ export { addEventProcessor, addBreadcrumb, addIntegration, + moduleMetadataIntegration, captureException, captureEvent, captureMessage, @@ -93,6 +96,7 @@ export { mcpServerIntegration, SentryMastraExporter, createFlueInstrumentation, + instrumentPostgresJsSql, modulesIntegration, contextLinesIntegration, nodeContextIntegration, @@ -176,6 +180,8 @@ export { instrumentGoogleGenAIClient, instrumentStateGraph, instrumentStateGraphCompile, + instrumentCreateReactAgent, + awsIntegration, zodErrorsIntegration, profiler, amqplibIntegration, diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts index 88ce8deaac01..8be218013d43 100644 --- a/packages/cloudflare/src/index.ts +++ b/packages/cloudflare/src/index.ts @@ -11,6 +11,8 @@ export type { FeatureFlagsIntegration, Session, SeverityLevel, + Log, + LogSeverityLevel, Span, StackFrame, Stacktrace, @@ -30,6 +32,7 @@ export { captureException, captureEvent, captureMessage, + parameterize, captureFeedback, close, createTransport, @@ -139,6 +142,7 @@ export { createLangChainCallbackHandler, instrumentLangChainEmbeddings, instrumentStateGraph, + instrumentStateGraphCompile, instrumentCreateReactAgent, vercelAIIntegration, honoIntegration, diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index f55fe14de14f..59b68d31034c 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -30,6 +30,7 @@ export { captureException, captureEvent, captureMessage, + parameterize, captureFeedback, close, createTransport, @@ -122,6 +123,7 @@ export { createLangChainCallbackHandler, instrumentLangChainEmbeddings, instrumentStateGraph, + instrumentStateGraphCompile, instrumentCreateReactAgent, } from '@sentry/server-utils'; export type { FlueOptions } from '@sentry/server-utils'; @@ -156,6 +158,7 @@ export { genericPoolIntegration, googleGenAIIntegration, graphqlIntegration, + fastifyIntegration, hapiIntegration, honoIntegration, honoMiddleware, diff --git a/packages/deno/test/exports.test.ts b/packages/deno/test/exports.test.ts index c1468653c566..76b4cce1cd18 100644 --- a/packages/deno/test/exports.test.ts +++ b/packages/deno/test/exports.test.ts @@ -12,6 +12,7 @@ const EXPECTED_FUNCTION_EXPORTS = [ 'createConsolaReporter', 'growthbookIntegration', 'moduleMetadataIntegration', + 'parameterize', // @sentry/core/server 'trpcMiddleware', // @sentry/server-utils @@ -24,7 +25,10 @@ const EXPECTED_FUNCTION_EXPORTS = [ 'createLangChainCallbackHandler', 'instrumentLangChainEmbeddings', 'instrumentStateGraph', + 'instrumentStateGraphCompile', 'instrumentCreateReactAgent', + // In the default integrations, so users who set `defaultIntegrations` can add it back + 'fastifyIntegration', // ./sdk 'initWithoutDefaultIntegrations', 'getDefaultIntegrationsWithoutPerformance', diff --git a/packages/google-cloud-serverless/src/index.ts b/packages/google-cloud-serverless/src/index.ts index b90e609bbfc1..2c4cb5726769 100644 --- a/packages/google-cloud-serverless/src/index.ts +++ b/packages/google-cloud-serverless/src/index.ts @@ -2,6 +2,7 @@ export { addEventProcessor, addBreadcrumb, addIntegration, + moduleMetadataIntegration, captureException, captureEvent, captureMessage, @@ -71,6 +72,7 @@ export { mcpServerIntegration, SentryMastraExporter, createFlueInstrumentation, + instrumentPostgresJsSql, modulesIntegration, nodeRuntimeMetricsIntegration, type NodeRuntimeMetricsOptions, @@ -156,6 +158,8 @@ export { instrumentGoogleGenAIClient, instrumentStateGraph, instrumentStateGraphCompile, + instrumentCreateReactAgent, + awsIntegration, zodErrorsIntegration, profiler, amqplibIntegration, diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 130194f72cf5..7cc711e110f0 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -6,6 +6,7 @@ export { expressErrorHandler, setupExpressErrorHandler } from '@sentry/server-ut export { amqplibIntegration, anthropicAIIntegration, + awsIntegration, dataloaderIntegration, expressIntegration, type ExpressIntegrationOptions, @@ -57,6 +58,8 @@ export { instrumentLangChainEmbeddings, instrumentStateGraph, instrumentStateGraphCompile, + instrumentCreateReactAgent, + instrumentPostgresJsSql, fastifyIntegration, // oxlint-disable-next-line typescript/no-deprecated setupFastifyErrorHandler, @@ -148,6 +151,7 @@ export { captureSession, endSession, addIntegration, + moduleMetadataIntegration, startSpan, startSpanManual, startInactiveSpan,