Skip to content

Commit bb329b5

Browse files
committed
feat(hono): Emit warning if @sentry/node was imported instead of @sentry/hono/node
1 parent 0a4c0cb commit bb329b5

2 files changed

Lines changed: 63 additions & 7 deletions

File tree

packages/hono/src/node/middleware.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type BaseTransportOptions, debug, type Options, getClient } from '@sentry/core';
1+
import { type BaseTransportOptions, consoleSandbox, debug, getClient, type Options } from '@sentry/core';
22
import type { Env, Hono, MiddlewareHandler } from 'hono';
33
import { requestHandler, responseHandler } from '../shared/middlewareHandlers';
44
import { applyPatches } from '../shared/applyPatches';
@@ -21,8 +21,19 @@ export const sentry = <E extends Env>(app: Hono<E>, options?: SentryHonoMiddlewa
2121
'Sentry is not initialized. Call `init()` from @sentry/hono/node in an `instrument.ts` file loaded via `--import` to set up Sentry for your application.',
2222
);
2323
} else {
24-
sentryClient.getOptions().debug &&
25-
debug.log('Sentry is initialized, proceeding to set up Hono `sentry` middleware.');
24+
const isInitializedWithHonoSdk = sentryClient.getOptions()._metadata?.sdk?.name === 'sentry.javascript.hono';
25+
26+
if (!isInitializedWithHonoSdk) {
27+
consoleSandbox(() => {
28+
// eslint-disable-next-line no-console
29+
console.warn(
30+
'[Sentry] Detected `Sentry.init` call from `@sentry/node` instead of `@sentry/hono/node`. Import from `@sentry/hono/node` to ensure Hono-specific instrumentation is applied correctly.',
31+
);
32+
});
33+
} else {
34+
sentryClient.getOptions().debug &&
35+
debug.log('Sentry is initialized, proceeding to set up Hono `sentry` middleware.');
36+
}
2637
}
2738

2839
applyPatches(app);

packages/hono/test/node/middleware.test.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,52 @@ describe('Hono Node Middleware', () => {
7272
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Sentry is not initialized'));
7373
});
7474

75-
it('does not emit a warning when Sentry is already initialized', () => {
75+
it('does not emit a warning when Sentry is already initialized with @sentry/hono/node', () => {
7676
const warnSpy = vi.spyOn(SentryCore.debug, 'warn');
77-
const fakeClient = { getOptions: () => ({ debug: false }) };
77+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
78+
const fakeClient = {
79+
getOptions: () => ({
80+
debug: false,
81+
_metadata: { sdk: { name: 'sentry.javascript.hono' } },
82+
}),
83+
};
7884
vi.spyOn(SentryCore, 'getClient').mockReturnValue(fakeClient as unknown as SentryCore.Client);
7985

8086
const app = new Hono();
8187
sentry(app);
8288

8389
expect(warnSpy).not.toHaveBeenCalled();
90+
expect(consoleWarnSpy).not.toHaveBeenCalled();
91+
consoleWarnSpy.mockRestore();
92+
});
93+
94+
it('emits a console.warn when Sentry is initialized with @sentry/node instead of @sentry/hono/node', () => {
95+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
96+
const fakeClient = {
97+
getOptions: () => ({
98+
debug: false,
99+
_metadata: { sdk: { name: 'sentry.javascript.node' } },
100+
}),
101+
};
102+
vi.spyOn(SentryCore, 'getClient').mockReturnValue(fakeClient as unknown as SentryCore.Client);
103+
104+
const app = new Hono();
105+
sentry(app);
106+
107+
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('@sentry/hono/node'));
108+
consoleWarnSpy.mockRestore();
109+
});
110+
111+
it('emits a console.warn when Sentry is initialized without any SDK metadata', () => {
112+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
113+
const fakeClient = { getOptions: () => ({ debug: false }) };
114+
vi.spyOn(SentryCore, 'getClient').mockReturnValue(fakeClient as unknown as SentryCore.Client);
115+
116+
const app = new Hono();
117+
sentry(app);
118+
119+
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('@sentry/hono/node'));
120+
consoleWarnSpy.mockRestore();
84121
});
85122
});
86123

@@ -145,16 +182,24 @@ describe('Hono Node Middleware', () => {
145182
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Sentry is not initialized'));
146183
});
147184

148-
it('does not emit a warning when Sentry is already initialized', () => {
185+
it('does not emit a warning when Sentry is already initialized with @sentry/hono/node', () => {
149186
const warnSpy = vi.spyOn(SentryCore.debug, 'warn');
150-
const fakeClient = { getOptions: () => ({ debug: false }) };
187+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
188+
const fakeClient = {
189+
getOptions: () => ({
190+
debug: false,
191+
_metadata: { sdk: { name: 'sentry.javascript.hono' } },
192+
}),
193+
};
151194
vi.spyOn(SentryCore, 'getClient').mockReturnValue(fakeClient as unknown as SentryCore.Client);
152195

153196
const app = new Hono();
154197
const middleware = sentry(app);
155198

156199
expect(warnSpy).not.toHaveBeenCalled();
200+
expect(consoleWarnSpy).not.toHaveBeenCalled();
157201
expect(middleware.constructor.name).toBe('AsyncFunction');
202+
consoleWarnSpy.mockRestore();
158203
});
159204
});
160205

0 commit comments

Comments
 (0)