Conversation
size-limit report 📦
|
e8a310d to
810fa6c
Compare
| { exportName: 'redisIntegration', modules: ['redis', '@redis/client', 'ioredis'] }, | ||
| { exportName: 'dataloaderIntegration', modules: ['dataloader'] }, | ||
| { exportName: 'nitroIntegration', modules: ['h3'] }, | ||
| { exportName: 'nitroServerTimingIntegration', modules: ['unstorage'] }, |
There was a problem hiding this comment.
Bug: The nitroServerTimingIntegration may silently fail to register on Cloudflare if unstorage is tree-shaken from a minimal Nitro app, breaking trace propagation.
Severity: MEDIUM
Suggested Fix
To ensure robust registration, the module dependency for nitroServerTimingIntegration should be changed from ['unstorage'] to ['h3']. Since h3 is a guaranteed dependency in any Nitro application, this change ensures the integration is always registered when needed. The configuration should be updated to { exportName: 'nitroServerTimingIntegration', modules: ['h3'] }.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location:
packages/server-utils/src/orchestrion/config/channel-integration-definitions.ts#L64
Potential issue: The registration of `nitroServerTimingIntegration` for Cloudflare
Workers is configured to trigger upon detection of the `unstorage` module. This relies
on the assumption that `unstorage` is a core, non-tree-shakable dependency in all Nitro
applications. However, if a minimal Nitro application can be built without `unstorage`,
the integration will silently fail to register. This would result in the `sentry-trace`
and `baggage` headers not being set, breaking distributed tracing for affected
applications without any error or warning.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
I added a fix for this in a separate PR on this stack here: #24897
260b8fd to
a2ec8d9
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d93c0f9. Configure here.
logaretm
left a comment
There was a problem hiding this comment.
Should we merge both nitro integrations into one integration that enables either instrumentation with options?
nitroIntegration({
// defaults, or flip em to `disabeXXX`
serverTiming: true,
storageInstrumentation: true,
// other instrumentations
})Extract Nitro's diagnostics-channel instrumentation out of `@sentry/nitro` into `@sentry/server-utils`, so any server SDK can provide it: - `nitroIntegration` (h3/srvx HTTP + middleware spans, unstorage cache spans) is a tracing integration, registered via `getTracingIntegrations()` and so available in node, deno and bun. - `nitroServerTimingIntegration` sets the `Server-Timing` trace-propagation headers. It is a default (non-tracing) integration so it also runs in tracing-without-performance mode, and can be opted out separately. Error capture stays in `@sentry/nitro`'s runtime plugin (its Nitro `error` hook), which a channel-based integration cannot replace without losing coverage. `@sentry/nitro` keeps getting all of this through the underlying `@sentry/node` defaults, so nothing changes for existing Nitro-on-Node apps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…orchestrion Add registration-only orchestrion configs so the Nitro integrations are auto-registered on bundler-only SDKs like `@sentry/cloudflare`, which discover a bundled module via the module-injected event and instantiate its factory. The snippet maps one integration per module, so two anchors are used, both core Nitro dependencies evaluated at startup: `h3` (dist/h3.mjs) registers `nitroIntegration` (spans) and `unstorage` (dist/index.mjs) registers `nitroServerTimingIntegration`. These are registration-only (no channels are injected, the libraries publish their own), so they are excluded from the runtime loader and are a no-op on node/deno/bun, where the integrations are registered statically. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…trion config Document why the h3/unstorage registration-only ranges use the `-0` suffix: the orchestrion matcher is the vendored `semifies` (not node-semver), where a range carrying a prerelease tag matches prereleases across patch tuples — so `>=2.0.0-0` matches the `2.0.1-rc.*` / `2.0.0-alpha.*` versions Nitro 3 ships. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a raw Nitro 3 app deployed to Cloudflare (Workers, `cloudflare_module` preset) that exercises the orchestrion registration-only path on a bundler-only SDK: the app imports no Nitro instrumentation, and `nitroIntegration` / `nitroServerTimingIntegration` are auto-injected via the orchestrion transform over h3/unstorage and instantiated by `@sentry/cloudflare` at init. Tests assert `auto.http.nitro.*` spans, `auto.cache.nitro` cache spans, and the `Server-Timing` trace-propagation header — i.e. the whole auto-injection path, including that the tracing channels bind under Cloudflare's async-context strategy. Init mirrors what @sentry/nuxt does for Nitro-on-Cloudflare (no first-class raw-Nitro Cloudflare helper exists): a Nitro server plugin wraps `nitroApp.fetch` with `wrapRequestHandler`, and the orchestrion rollup/rolldown plugin is wired into the Nitro build config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This reverts commit ab0b58f.
The `mod.test.ts` snapshots captured the full `sdk.integrations` list, so any change to the default integrations (such as the new nitro integrations) broke them even though the list is incidental to what these tests verify. Normalize `sdk.integrations` to a placeholder, like the other volatile fields. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stacked on develop's hono size bump: the nitro integrations add on top, so @sentry/node needs 146 KB and the no-channel-injection variant 125 KB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`nitroIntegration` is part of the Node tracing integrations, but the Nitro SDK should always include it regardless of that gating. Add it explicitly to the Nitro SDK's default integrations (deduped by name when both are added), and re-export `nitroIntegration`/`nitroServerTimingIntegration` from `@sentry/node`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nitroIntegration and nitroServerTimingIntegration are exported from @sentry/node, so every SDK with an explicit re-export list needs them too (caught by the node-exports-test-app consistency check). Deno and Bun also enable them by default via getTracingIntegrations(). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d93c0f9 to
a6ecc88
Compare
JPeer264
left a comment
There was a problem hiding this comment.
LGTM. The merge conflict might be the release we've just done
|
|
||
| const INTEGRATION_NAME = 'Nitro'; | ||
|
|
||
| const _nitroIntegration = (() => { |
There was a problem hiding this comment.
l: Would be nice if we could add a node integration test for this somehow that will run it for bun and deno. Then we would have proof that it would run on these runtimes. Wdyt?
| import { captureTracingEvents } from './captureTracingEvents'; | ||
| import { captureServerTimingHeaders } from './setServerTimingHeaders'; | ||
|
|
||
| const INTEGRATION_NAME = 'Nitro'; |
There was a problem hiding this comment.
l:
| const INTEGRATION_NAME = 'Nitro'; | |
| const INTEGRATION_NAME = 'Nitro' as const; |
| */ | ||
| export const nitroIntegration = defineIntegration(_nitroIntegration); | ||
|
|
||
| const SERVER_TIMING_INTEGRATION_NAME = 'NitroServerTiming'; |
There was a problem hiding this comment.
l:
| const SERVER_TIMING_INTEGRATION_NAME = 'NitroServerTiming'; | |
| const SERVER_TIMING_INTEGRATION_NAME = 'NitroServerTiming' as const; |
Currently they are added independently as tracing and error integration within Nitro Btw I think the PR description is stale, there are no e2e tests in here anymore |
Yea, that was never the intention of them I think. This happened as a side effect of other changes. I think rarely anyone will use one without the other. |

Moves Nitro's
node:diagnostics_channel-based instrumentation out of@sentry/nitroand into@sentry/server-utils, so it is no longer tied to the Nitro package and can be provided by any server SDK. This mirrors the Hono → server-utils move.The runtime instrumentation splits into two integrations:
nitroIntegration— h3/srvx HTTP + middleware spans and unstorage cache spans. It only creates spans, so it is a tracing integration, registered viagetTracingIntegrations(). That makes it available (and on by default) in node, deno and bun.nitroServerTimingIntegration— sets theServer-Timingresponse headers that carrysentry-trace/baggageso the browser SDK can connect a pageload to the backend trace. This must work even when tracing is disabled (trace-without-performance), so it is a default (non-tracing) integration, registered viagetErrorIntegrations(). It is opt-out-able independently.Both integrations subscribe to h3's tracing channels, so they are inert unless a Nitro app (the only real emitter of those channels) is running.
Cloudflare (and other bundler-only SDKs) get both integrations auto-injected via orchestrion registration-only configs: h3 and unstorage are transformed at build time to register the matching factory, which
@sentry/cloudflareinstantiates atinit(). These are registration-only (no channels injected — the libraries publish their own), so they are excluded from the runtime loader and are a no-op on node/deno/bun, where the integrations are registered statically.Non-breaking:
@sentry/nitro'sinit()goes through@sentry/node's default integrations, which now include both of the above, so existing Nitro-on-Node apps get exactly the same spans and headers as before — just sourced from the integrations rather than the runtime plugin.@sentry/nitrono longer depends on@sentry/server-utils.Why error capture stays in
@sentry/nitroError capture is intentionally not moved. Nitro's
errorhook is a broad boundary (request/response-hook, plugin-init, cache and process-levelunhandled*errors, pluscontexts.nitrotags/method/path). The tracing channels only see errors thrown through a traced handler, so folding error capture into a channel-based integration would lose coverage and force an h3 coupling into the framework-neutral package. It remains in the Nitro runtime plugin'serrorhook.E2E coverage
A new
cloudflare-nitroe2e app (raw Nitro 3 on thecloudflare_modulepreset) exercises the Cloudflare auto-injection end to end — assertingauto.http.nitro.*spans,auto.cache.nitrocache spans, and theServer-Timingheader, which also confirms the tracing channels bind under Cloudflare's async-context strategy. Since raw Nitro has no first-class Cloudflare init helper yet, the app wires init by hand (a Nitro server plugin wrappingnitroApp.fetchwithwrapRequestHandler, mirroring@sentry/nuxt); a supported helper could be a good follow-up.🤖 Generated with Claude Code