Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"//": "Need to use ioredis 5.10.1 because that's the last version before they support tracing channels",
"dependencies": {
"@sentry/tanstackstart-react": "file:../../packed/sentry-tanstackstart-react-packed.tgz",
"@sentry/server-utils": "file:../../packed/sentry-server-utils-packed.tgz",
"@tanstack/react-start": "^1.136.0",
"@tanstack/react-router": "^1.136.0",
"react": "^19.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import viteReact from '@vitejs/plugin-react-swc';
import { nitro } from 'nitro/vite';
import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite';
import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';

const appDsn = 'http://public@localhost:3031/1337';

Expand All @@ -28,9 +27,5 @@ export default defineConfig({
authToken: process.env.E2E_TEST_AUTH_TOKEN,
debug: true,
}),
// Runs the orchestrion code transform over the server bundle and
// force-bundles the instrumented deps (mysql, ioredis, …) so the
// diagnostics-channel calls are actually injected.
sentryOrchestrionPlugin(),
],
});
1 change: 1 addition & 0 deletions packages/tanstackstart-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"@sentry/core": "10.67.0",
"@sentry/node": "10.67.0",
"@sentry/react": "10.67.0",
"@sentry/server-utils": "10.67.0",
"@sentry/bundler-plugins": "10.67.0"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { BuildTimeOptionsBase } from '@sentry/core';
import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';
import type { Plugin } from 'vite';
import { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware';
import { makeRoutePatternPlugin } from './routePatterns';
Expand Down Expand Up @@ -96,6 +97,11 @@ export function sentryTanstackStart(options: SentryTanstackStartOptions = {}): P
return plugins;
}

// Runs the orchestrion code transform over the server bundle so instrumented DB drivers get
// `diagnostics_channel` publishers injected. Production-only: it force-bundles the instrumented
// (CommonJS) deps via `ssr.noExternal`, which the `vite dev` SSR module runner can't evaluate.
plugins.push(sentryOrchestrionPlugin({ buildTimeInstrumentation: options.buildTimeInstrumentation }));

plugins.push(...makeAddSentryVitePlugin(options));

// middleware auto-instrumentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ const mockRoutePatternPlugin: Plugin = {
config: vi.fn(),
};

// Stub the orchestrion plugin so these stay pure wiring tests (no apm code transformer pulled in).
// Mirror the real plugin's contract: `buildTimeInstrumentation: false` yields the inert variant.
const orchestrionVite = vi.fn((options?: { buildTimeInstrumentation?: boolean }) => ({
name: options?.buildTimeInstrumentation === false ? 'sentry-orchestrion-disabled' : 'sentry-orchestrion-vite',
}));
vi.mock('@sentry/server-utils/orchestrion/vite', () => ({
sentryOrchestrionPlugin: (options?: { buildTimeInstrumentation?: boolean }) => orchestrionVite(options),
}));

const mockOrchestrionPlugin: Plugin = { name: 'sentry-orchestrion-vite' };

vi.mock('../../src/vite/routePatterns', () => ({
makeRoutePatternPlugin: vi.fn(() => mockRoutePatternPlugin),
}));
Expand Down Expand Up @@ -74,13 +85,14 @@ describe('sentryTanstackStart()', () => {

expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
mockEnableSourceMapsPlugin,
]);
});

it('returns no plugins in development mode when tunnelRoute is not configured', () => {
it('returns no build-time plugins in development mode when tunnelRoute is not configured', () => {
process.env.NODE_ENV = 'development';

const plugins = sentryTanstackStart({ autoInstrumentMiddleware: false });
Expand All @@ -105,7 +117,12 @@ describe('sentryTanstackStart()', () => {
sourcemaps: { disable: true },
});

expect(plugins).toEqual([mockRoutePatternPlugin, mockSourceMapsConfigPlugin, mockSentryVitePlugin]);
expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
]);
});

it('returns Sentry Vite plugins but not enable source maps plugin when sourcemaps.disable is "disable-upload"', () => {
Expand All @@ -114,7 +131,12 @@ describe('sentryTanstackStart()', () => {
sourcemaps: { disable: 'disable-upload' },
});

expect(plugins).toEqual([mockRoutePatternPlugin, mockSourceMapsConfigPlugin, mockSentryVitePlugin]);
expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
]);
});

it('returns Sentry Vite plugins and enable source maps plugin when sourcemaps.disable is false', () => {
Expand All @@ -125,6 +147,7 @@ describe('sentryTanstackStart()', () => {

expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
mockEnableSourceMapsPlugin,
Expand All @@ -138,6 +161,7 @@ describe('sentryTanstackStart()', () => {

expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
mockMiddlewarePlugin,
Expand All @@ -152,6 +176,7 @@ describe('sentryTanstackStart()', () => {

expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
mockMiddlewarePlugin,
Expand All @@ -164,7 +189,12 @@ describe('sentryTanstackStart()', () => {
sourcemaps: { disable: true },
});

expect(plugins).toEqual([mockRoutePatternPlugin, mockSourceMapsConfigPlugin, mockSentryVitePlugin]);
expect(plugins).toEqual([
mockRoutePatternPlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
]);
});

it('passes correct options to makeAutoInstrumentMiddlewarePlugin', () => {
Expand Down Expand Up @@ -193,6 +223,7 @@ describe('sentryTanstackStart()', () => {
expect(plugins).toEqual([
mockRoutePatternPlugin,
mockTunnelRoutePlugin,
mockOrchestrionPlugin,
mockSourceMapsConfigPlugin,
mockSentryVitePlugin,
mockMiddlewarePlugin,
Expand All @@ -213,4 +244,33 @@ describe('sentryTanstackStart()', () => {
expect(makeTunnelRoutePlugin).toHaveBeenCalledWith(options.tunnelRoute, undefined);
});
});

describe('orchestrion build-time instrumentation', () => {
it('adds the orchestrion plugin by default', () => {
const plugins = sentryTanstackStart({ sourcemaps: { disable: true } });

expect(orchestrionVite).toHaveBeenCalledWith({ buildTimeInstrumentation: undefined });
expect(plugins.map(plugin => plugin.name)).toContain('sentry-orchestrion-vite');
});

it('does not add the orchestrion plugin in development mode', () => {
process.env.NODE_ENV = 'development';

const plugins = sentryTanstackStart({ sourcemaps: { disable: true } });

// Orchestrion force-bundles the instrumented (CommonJS) deps via `ssr.noExternal`, which the
// `vite dev` SSR module runner can't evaluate — so it's a production-only transform.
expect(orchestrionVite).not.toHaveBeenCalled();
expect(plugins.map(plugin => plugin.name)).not.toContain('sentry-orchestrion-vite');
});

it('adds an inert orchestrion plugin when `buildTimeInstrumentation` is `false`', () => {
const plugins = sentryTanstackStart({ buildTimeInstrumentation: false, sourcemaps: { disable: true } });
const pluginNames = plugins.map(plugin => plugin.name);

expect(orchestrionVite).toHaveBeenCalledWith({ buildTimeInstrumentation: false });
expect(pluginNames).toContain('sentry-orchestrion-disabled');
expect(pluginNames).not.toContain('sentry-orchestrion-vite');
});
});
});
Loading