ref(server-utils): Move server-only utils out of core - #23826
Conversation
Moves a batch of server-only helpers out of `@sentry/core/server` into `@sentry/server-utils`, continuing the effort to slim `@sentry/core` down to the isomorphic surface. The moved symbols only ever depended on the public `@sentry/core` API (plus the `@sentry/core/server` `filenameIsInApp` for anr), so they relocate cleanly without expanding core's public surface. Moved: - `flushIfServerless` + `vercelWaitUntil` (used by the meta-framework SDKs) - `trpcMiddleware` - `callFrameToStackFrame` / `watchdogTimer` (the anr worker helpers) - `loadModule` (split out of `utils/node`, `isNodeEnv` stays in core since core itself depends on it via `isBrowser`) Every consumer already depends on `@sentry/server-utils`, so this only changes the internal import path; the public SDK packages keep re-exporting these under the same names, so there is no user-facing change. `mcp-server` and the `integrations/http/*` subtree are intentionally left in core for now: unlike the above, they import a number of non-public core internals (`getSpanName`, `resolveDataCollectionOptions`, `getBreadcrumbLogLevel`, `getDefaultExport`, `generatePropagationContext`, the internal `client`/`scope` modules), so moving them would require promoting those to core's public API — a separate decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
172fba6 to
d52ac53
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 d52ac53. Configure here.
| } from '@sentry/core'; | ||
| export { trpcMiddleware, wrapMcpServerWithSentry } from '@sentry/core/server'; | ||
| export { wrapMcpServerWithSentry } from '@sentry/core/server'; | ||
| export { trpcMiddleware } from '@sentry/server-utils'; |
There was a problem hiding this comment.
Edge SDKs import Node-only barrel
Medium Severity
trpcMiddleware is re-exported from the main @sentry/server-utils entry, which evaluates Node-only modules such as node:diagnostics_channel and node:async_hooks. @sentry/vercel-edge already takes the rest of its server-utils imports from @sentry/server-utils/no-diagnostic-channels, which also re-exports trpcMiddleware. Importing the Node barrel from an edge entry can break bundling or startup in non-Node runtimes.
Additional Locations (1)
Triggered by project rule: PR Review Guidelines for Cursor Bot
Reviewed by Cursor Bugbot for commit d52ac53. Configure here.
|
Folded into #23833, which now contains this move plus the ServerRuntimeClient/node-stack-parser move as a single commit targeting |


Continues slimming
@sentry/coretoward the isomorphic surface by moving a batch of server-only helpers out of@sentry/core/serverinto@sentry/server-utils(following the same pattern as the browser span-API move).Moved to
@sentry/server-utils:flushIfServerless+vercelWaitUntiltrpcMiddlewarecallFrameToStackFrame/watchdogTimer(anr worker helpers)loadModule(split out ofutils/node)Why these are safe to move: each only depended on the public
@sentry/coreAPI (anr additionally usesfilenameIsInAppfrom@sentry/core/server, which stays), so nothing in core's public surface had to be expanded. Every consumer already depends on@sentry/server-utils, so this only changes the internal import path — the public SDK packages (@sentry/node,@sentry/nextjs, …) keep re-exporting these under the same names, so there is no user-facing change.Decisions:
isNodeEnvstays in@sentry/core: core itself depends on it (viaisBrowser), so it cannot move without a cycle.loadModulewas split out of the sameutils/nodefile.mcp-serverand theintegrations/http/*subtree are deliberately left in core. Unlike the helpers above, they import several non-public core internals (getSpanName,resolveDataCollectionOptions,getBreadcrumbLogLevel,getDefaultExport,generatePropagationContext, and the internalclient/scopemodules). Moving them would require promoting those internals to core's public API, which is a separate call to make.@sentry/server-utilsand rewritten to spy on the public@sentry/corenamespace; consumer test mocks were retargeted from@sentry/core/serverto@sentry/server-utils(using light full-replacement mocks rather thanimportOriginal, to avoid force-loading the whole server-utils integration graph).