Skip to content

Commit c1e182c

Browse files
fix(hono): Return the existing client on repeated init in Bun and Deno (#24520)
On Bun and Deno, `init()` warned when Sentry was already initialized but then initialized again, replacing the client. Anything buffered on the first client was dropped and its integrations stayed installed against it. Both now keep the warning and return the existing client, as the Node entry already does. Node's behavior is unchanged (it only logs in debug mode, since it is initialized from an instrument file); Cloudflare initializes per request through `withSentry` and is not affected. Closes #24049 Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 90db319 commit c1e182c

4 files changed

Lines changed: 28 additions & 6 deletions

File tree

‎packages/hono/src/bun/sdk.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ import { LOW_QUALITY_TRANSACTION_PATTERNS } from '../shared/lowQualityTransactio
1313
* When manually calling `init`, add the `honoIntegration` to the `integrations` array to set up the Hono integration.
1414
*/
1515
export function init(options: HonoBunOptions): Client | undefined {
16-
if (getClient()) {
16+
const existingClient = getClient();
17+
if (existingClient) {
1718
consoleSandbox(() => {
1819
// eslint-disable-next-line no-console
1920
console.warn(
2021
'[Sentry] Sentry is already initialized. Sentry should only be initialized once, through the `sentry()` middleware. Remove the `Sentry.init()` call, if one exists.',
2122
);
2223
});
24+
// Re-initializing would replace the client and drop anything buffered on it
25+
return existingClient;
2326
}
2427

2528
applySdkMetadata(options, 'hono', ['hono', 'bun']);

‎packages/hono/src/deno/sdk.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ import { LOW_QUALITY_TRANSACTION_PATTERNS } from '../shared/lowQualityTransactio
1313
* When manually calling `init`, add the `honoIntegration` to the `integrations` array to set up the Hono integration.
1414
*/
1515
export function init(options: HonoDenoOptions): Client | undefined {
16-
if (getClient()) {
16+
const existingClient = getClient();
17+
if (existingClient) {
1718
consoleSandbox(() => {
1819
// eslint-disable-next-line no-console
1920
console.warn(
2021
'[Sentry] Sentry is already initialized. Sentry should only be initialized once, through the `sentry()` middleware. Remove the `Sentry.init()` call, if one exists.',
2122
);
2223
});
24+
// Re-initializing would replace the client and drop anything buffered on it
25+
return existingClient;
2326
}
2427

2528
applySdkMetadata(options, 'hono', ['hono', 'deno']);

‎packages/hono/test/bun/middleware.test.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,22 @@ describe('Hono Bun Middleware', () => {
171171
});
172172

173173
describe('double-init guard', () => {
174-
it('still calls init even when Sentry is already initialized', () => {
174+
it('does not re-initialize when Sentry is already initialized', () => {
175175
const fakeClient = { getOptions: () => ({}) };
176176
getClientMock.mockReturnValue(fakeClient as unknown as SentryCore.Client);
177177

178178
const app = new Hono();
179179
sentry(app, { dsn: 'https://public@dsn.ingest.sentry.io/1337' });
180180

181-
expect(initBunMock).toHaveBeenCalledTimes(1);
181+
expect(initBunMock).not.toHaveBeenCalled();
182+
});
183+
184+
it('returns the existing client when Sentry is already initialized', () => {
185+
const fakeClient = { getOptions: () => ({}) };
186+
getClientMock.mockReturnValue(fakeClient as unknown as SentryCore.Client);
187+
188+
expect(init({ dsn: 'https://public@dsn.ingest.sentry.io/1337' })).toBe(fakeClient);
189+
expect(initBunMock).not.toHaveBeenCalled();
182190
});
183191

184192
it('emits a console.warn directing to remove the duplicate init call when Sentry is already initialized', () => {

‎packages/hono/test/deno/middleware.test.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,22 @@ describe('Hono Deno Middleware', () => {
171171
});
172172

173173
describe('double-init guard', () => {
174-
it('still calls init even when Sentry is already initialized', () => {
174+
it('does not re-initialize when Sentry is already initialized', () => {
175175
const fakeClient = { getOptions: () => ({}) };
176176
getClientMock.mockReturnValue(fakeClient as unknown as SentryCore.Client);
177177

178178
const app = new Hono();
179179
sentry(app, { dsn: 'https://public@dsn.ingest.sentry.io/1337' });
180180

181-
expect(initDenoMock).toHaveBeenCalledTimes(1);
181+
expect(initDenoMock).not.toHaveBeenCalled();
182+
});
183+
184+
it('returns the existing client when Sentry is already initialized', () => {
185+
const fakeClient = { getOptions: () => ({}) };
186+
getClientMock.mockReturnValue(fakeClient as unknown as SentryCore.Client);
187+
188+
expect(init({ dsn: 'https://public@dsn.ingest.sentry.io/1337' })).toBe(fakeClient);
189+
expect(initDenoMock).not.toHaveBeenCalled();
182190
});
183191

184192
it('emits a console.warn directing to remove the duplicate init call when Sentry is already initialized', () => {

0 commit comments

Comments
 (0)