From f40eb35fe8d3a207dbe80f1ee2f7e28c6a71af9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:48:08 +0000 Subject: [PATCH 01/12] Initial plan From 1438d5bfd2158e549e209780555f28d5b6c9e93b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:57:00 +0000 Subject: [PATCH 02/12] Fix client.flush() blocking process exit with unref'd timers and early exit Co-authored-by: Lms24 <8420481+Lms24@users.noreply.github.com> --- packages/core/src/client.ts | 14 +++++- packages/core/src/utils/promisebuffer.ts | 12 ++++- packages/core/test/lib/client.test.ts | 44 +++++++++++++++++++ .../core/test/lib/utils/promisebuffer.test.ts | 13 ++++++ packages/node-core/test/sdk/client.test.ts | 30 +++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 56b382a2860e..1f64b1bd65d4 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1148,11 +1148,23 @@ export abstract class Client { * `false` otherwise */ protected async _isClientDoneProcessing(timeout?: number): Promise { + // Early exit if there's nothing to process + if (!this._numProcessing) { + return true; + } + let ticked = 0; // if no timeout is provided, we wait "forever" until everything is processed while (!timeout || ticked < timeout) { - await new Promise(resolve => setTimeout(resolve, 1)); + await new Promise(resolve => { + const timer = setTimeout(resolve, 1); + // Use unref() in Node.js to allow the process to exit naturally + // In browsers, setTimeout returns a number, so we check for that + if (typeof timer !== 'number' && timer.unref) { + timer.unref(); + } + }); if (!this._numProcessing) { return true; diff --git a/packages/core/src/utils/promisebuffer.ts b/packages/core/src/utils/promisebuffer.ts index f66077a76fd5..7bc398acc054 100644 --- a/packages/core/src/utils/promisebuffer.ts +++ b/packages/core/src/utils/promisebuffer.ts @@ -77,7 +77,17 @@ export function makePromiseBuffer(limit: number = 100): PromiseBuffer { return drainPromise; } - const promises = [drainPromise, new Promise(resolve => setTimeout(() => resolve(false), timeout))]; + const promises = [ + drainPromise, + new Promise(resolve => { + const timer = setTimeout(() => resolve(false), timeout); + // Use unref() in Node.js to allow the process to exit naturally + // In browsers, setTimeout returns a number, so we check for that + if (typeof timer !== 'number' && timer.unref) { + timer.unref(); + } + }), + ]; // Promise.race will resolve to the first promise that resolves or rejects // So if the drainPromise resolves, the timeout promise will be ignored diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index 0945af5f019f..8e36da177134 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2205,6 +2205,50 @@ describe('Client', () => { }), ]); }); + + test('flush returns immediately when nothing is processing', async () => { + vi.useRealTimers(); + expect.assertions(2); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + const client = new TestClient(options); + + const startTime = Date.now(); + const result = await client.flush(1000); + const elapsed = Date.now() - startTime; + + // Should return true immediately without waiting + expect(result).toBe(true); + // Should take less than 100ms (much less than the 1000ms timeout) + expect(elapsed).toBeLessThan(100); + }); + + test('flush with early exit when processing completes', async () => { + vi.useRealTimers(); + expect.assertions(3); + + const { makeTransport, getSendCalled, getSentCount, delay } = makeFakeTransport(50); + + const client = new TestClient( + getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + enableSend: true, + transport: makeTransport, + }), + ); + + client.captureMessage('test'); + expect(getSendCalled()).toEqual(1); + + const startTime = Date.now(); + // Use a large timeout but processing should complete early + await client.flush(5000); + const elapsed = Date.now() - startTime; + + expect(getSentCount()).toEqual(1); + // Should complete in ~50ms (the transport delay), not wait for the full 5000ms timeout + expect(elapsed).toBeLessThan(500); + }); }); describe('sendEvent', () => { diff --git a/packages/core/test/lib/utils/promisebuffer.test.ts b/packages/core/test/lib/utils/promisebuffer.test.ts index d1b4b9abc48d..d375d0ba5b97 100644 --- a/packages/core/test/lib/utils/promisebuffer.test.ts +++ b/packages/core/test/lib/utils/promisebuffer.test.ts @@ -252,4 +252,17 @@ describe('PromiseBuffer', () => { expect(e).toEqual(new Error('whoops')); } }); + + test('drain returns immediately when buffer is empty', async () => { + const buffer = makePromiseBuffer(); + expect(buffer.$.length).toEqual(0); + + const startTime = Date.now(); + const result = await buffer.drain(5000); + const elapsed = Date.now() - startTime; + + expect(result).toBe(true); + // Should return immediately, not wait for timeout + expect(elapsed).toBeLessThan(100); + }); }); diff --git a/packages/node-core/test/sdk/client.test.ts b/packages/node-core/test/sdk/client.test.ts index 0bcef2669095..c88e1a256785 100644 --- a/packages/node-core/test/sdk/client.test.ts +++ b/packages/node-core/test/sdk/client.test.ts @@ -386,4 +386,34 @@ describe('NodeClient', () => { expect(processOffSpy).toHaveBeenNthCalledWith(1, 'beforeExit', expect.any(Function)); }); }); + + describe('flush', () => { + it('flush returns immediately when nothing is processing', async () => { + const options = getDefaultNodeClientOptions(); + const client = new NodeClient(options); + + const startTime = Date.now(); + const result = await client.flush(1000); + const elapsed = Date.now() - startTime; + + // Should return true immediately without waiting + expect(result).toBe(true); + // Should take less than 100ms (much less than the 1000ms timeout) + expect(elapsed).toBeLessThan(100); + }); + + it('flush does not block process exit when using unref timers', async () => { + // This test verifies that timers are properly unref'd in Node.js + // We create a client with no processing and a long timeout + const options = getDefaultNodeClientOptions(); + const client = new NodeClient(options); + + // Flush with a long timeout - if timers are not unref'd, this would block + const flushPromise = client.flush(5000); + + // The flush should complete immediately since there's nothing to process + const result = await flushPromise; + expect(result).toBe(true); + }); + }); }); From f9f3f6b72d2da24a47cce22b6f8af45a49a8eea2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:59:21 +0000 Subject: [PATCH 03/12] Fix lint error in client.test.ts Co-authored-by: Lms24 <8420481+Lms24@users.noreply.github.com> --- packages/core/test/lib/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index 8e36da177134..c2a8122478b6 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2227,7 +2227,7 @@ describe('Client', () => { vi.useRealTimers(); expect.assertions(3); - const { makeTransport, getSendCalled, getSentCount, delay } = makeFakeTransport(50); + const { makeTransport, getSendCalled, getSentCount } = makeFakeTransport(50); const client = new TestClient( getDefaultTestClientOptions({ From dfa682b24ca56cd4f120b9696f0fb7a1612e9e0f Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 28 Jan 2026 18:21:36 +0100 Subject: [PATCH 04/12] deslop --- packages/core/src/client.ts | 4 ---- packages/core/src/utils/promisebuffer.ts | 4 ---- packages/core/test/lib/client.test.ts | 7 ++----- packages/core/test/lib/utils/promisebuffer.test.ts | 1 - packages/node-core/test/sdk/client.test.ts | 12 ++---------- 5 files changed, 4 insertions(+), 24 deletions(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 1f64b1bd65d4..73b11219d908 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1148,19 +1148,15 @@ export abstract class Client { * `false` otherwise */ protected async _isClientDoneProcessing(timeout?: number): Promise { - // Early exit if there's nothing to process if (!this._numProcessing) { return true; } let ticked = 0; - // if no timeout is provided, we wait "forever" until everything is processed while (!timeout || ticked < timeout) { await new Promise(resolve => { const timer = setTimeout(resolve, 1); - // Use unref() in Node.js to allow the process to exit naturally - // In browsers, setTimeout returns a number, so we check for that if (typeof timer !== 'number' && timer.unref) { timer.unref(); } diff --git a/packages/core/src/utils/promisebuffer.ts b/packages/core/src/utils/promisebuffer.ts index 7bc398acc054..b930af3d3947 100644 --- a/packages/core/src/utils/promisebuffer.ts +++ b/packages/core/src/utils/promisebuffer.ts @@ -81,16 +81,12 @@ export function makePromiseBuffer(limit: number = 100): PromiseBuffer { drainPromise, new Promise(resolve => { const timer = setTimeout(() => resolve(false), timeout); - // Use unref() in Node.js to allow the process to exit naturally - // In browsers, setTimeout returns a number, so we check for that if (typeof timer !== 'number' && timer.unref) { timer.unref(); } }), ]; - // Promise.race will resolve to the first promise that resolves or rejects - // So if the drainPromise resolves, the timeout promise will be ignored return Promise.race(promises); } diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index c2a8122478b6..572524143658 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2217,9 +2217,7 @@ describe('Client', () => { const result = await client.flush(1000); const elapsed = Date.now() - startTime; - // Should return true immediately without waiting expect(result).toBe(true); - // Should take less than 100ms (much less than the 1000ms timeout) expect(elapsed).toBeLessThan(100); }); @@ -2241,13 +2239,12 @@ describe('Client', () => { expect(getSendCalled()).toEqual(1); const startTime = Date.now(); - // Use a large timeout but processing should complete early await client.flush(5000); const elapsed = Date.now() - startTime; expect(getSentCount()).toEqual(1); - // Should complete in ~50ms (the transport delay), not wait for the full 5000ms timeout - expect(elapsed).toBeLessThan(500); + // if this flakes, remove the test + expect(elapsed).toBeLessThan(1000); }); }); diff --git a/packages/core/test/lib/utils/promisebuffer.test.ts b/packages/core/test/lib/utils/promisebuffer.test.ts index d375d0ba5b97..8d45d426b1a4 100644 --- a/packages/core/test/lib/utils/promisebuffer.test.ts +++ b/packages/core/test/lib/utils/promisebuffer.test.ts @@ -262,7 +262,6 @@ describe('PromiseBuffer', () => { const elapsed = Date.now() - startTime; expect(result).toBe(true); - // Should return immediately, not wait for timeout expect(elapsed).toBeLessThan(100); }); }); diff --git a/packages/node-core/test/sdk/client.test.ts b/packages/node-core/test/sdk/client.test.ts index c88e1a256785..cf33049c1ffa 100644 --- a/packages/node-core/test/sdk/client.test.ts +++ b/packages/node-core/test/sdk/client.test.ts @@ -396,23 +396,15 @@ describe('NodeClient', () => { const result = await client.flush(1000); const elapsed = Date.now() - startTime; - // Should return true immediately without waiting expect(result).toBe(true); - // Should take less than 100ms (much less than the 1000ms timeout) expect(elapsed).toBeLessThan(100); }); - it('flush does not block process exit when using unref timers', async () => { - // This test verifies that timers are properly unref'd in Node.js - // We create a client with no processing and a long timeout + it('flush does not block process exit with unref timers', async () => { const options = getDefaultNodeClientOptions(); const client = new NodeClient(options); - // Flush with a long timeout - if timers are not unref'd, this would block - const flushPromise = client.flush(5000); - - // The flush should complete immediately since there's nothing to process - const result = await flushPromise; + const result = await client.flush(5000); expect(result).toBe(true); }); }); From 92aa12150423b62bb1aff6375a5bc2298dfc80a4 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 28 Jan 2026 18:35:25 +0100 Subject: [PATCH 05/12] extract safeUnref --- packages/core/src/client.ts | 8 ++---- packages/core/src/utils/promisebuffer.ts | 8 ++---- packages/core/src/utils/timer.ts | 15 ++++++++++ packages/core/test/lib/utils/timer.test.ts | 32 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 packages/core/src/utils/timer.ts create mode 100644 packages/core/test/lib/utils/timer.test.ts diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 73b11219d908..daff0bf728fa 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -49,6 +49,7 @@ import { safeMathRandom } from './utils/randomSafeContext'; import { reparentChildSpans, shouldIgnoreSpan } from './utils/should-ignore-span'; import { showSpanDropWarning } from './utils/spanUtils'; import { rejectedSyncPromise } from './utils/syncpromise'; +import { safeUnref } from './utils/timer'; import { convertSpanJsonToTransactionEvent, convertTransactionEventToSpanJson } from './utils/transactionEvent'; const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured."; @@ -1155,12 +1156,7 @@ export abstract class Client { let ticked = 0; while (!timeout || ticked < timeout) { - await new Promise(resolve => { - const timer = setTimeout(resolve, 1); - if (typeof timer !== 'number' && timer.unref) { - timer.unref(); - } - }); + await new Promise(resolve => safeUnref(setTimeout(resolve, 1))); if (!this._numProcessing) { return true; diff --git a/packages/core/src/utils/promisebuffer.ts b/packages/core/src/utils/promisebuffer.ts index b930af3d3947..4868e30f14b8 100644 --- a/packages/core/src/utils/promisebuffer.ts +++ b/packages/core/src/utils/promisebuffer.ts @@ -1,4 +1,5 @@ import { rejectedSyncPromise, resolvedSyncPromise } from './syncpromise'; +import { safeUnref } from './timer'; export interface PromiseBuffer { // exposes the internal array so tests can assert on the state of it. @@ -79,12 +80,7 @@ export function makePromiseBuffer(limit: number = 100): PromiseBuffer { const promises = [ drainPromise, - new Promise(resolve => { - const timer = setTimeout(() => resolve(false), timeout); - if (typeof timer !== 'number' && timer.unref) { - timer.unref(); - } - }), + new Promise(resolve => safeUnref(setTimeout(() => resolve(false), timeout))), ]; return Promise.race(promises); diff --git a/packages/core/src/utils/timer.ts b/packages/core/src/utils/timer.ts new file mode 100644 index 000000000000..f7d621ab8a6c --- /dev/null +++ b/packages/core/src/utils/timer.ts @@ -0,0 +1,15 @@ +/** + * Calls `unref` on a timer, if the method is available on @param timer. + * + * `unred()` is used to allow processes to exit immediately, even if the timer + * is still running and hasn't resolved yet. + * + * Use this in places where code can run on browser or server, since browsers + * do not support `unref`. + */ +export function safeUnref(timer: ReturnType): ReturnType { + if (typeof timer === 'object' && typeof timer.unref === 'function') { + timer.unref(); + } + return timer; +} diff --git a/packages/core/test/lib/utils/timer.test.ts b/packages/core/test/lib/utils/timer.test.ts new file mode 100644 index 000000000000..cd3b99fa4246 --- /dev/null +++ b/packages/core/test/lib/utils/timer.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it, vi } from 'vitest'; +import { safeUnref } from '../../../src/utils/timer'; + +describe('safeUnref', () => { + it('calls unref on a NodeJS timer', () => { + const timeout = setTimeout(() => {}, 1000); + const unrefSpy = vi.spyOn(timeout, 'unref'); + safeUnref(timeout); + expect(unrefSpy).toHaveBeenCalledOnce(); + }); + + it('returns the timer', () => { + const timeout = setTimeout(() => {}, 1000); + const result = safeUnref(timeout); + expect(result).toBe(timeout); + }); + + it('handles multiple unref calls', () => { + const timeout = setTimeout(() => {}, 1000); + const unrefSpy = vi.spyOn(timeout, 'unref'); + + const result = safeUnref(timeout); + result.unref(); + + expect(unrefSpy).toHaveBeenCalledTimes(2); + }); + + it("doesn't throw for a browser timer", () => { + const timer = safeUnref(385 as unknown as ReturnType); + expect(timer).toBe(385); + }); +}); From 8746622e507a9cbdc5a5537a3d667bf4e4352a89 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 13:46:21 +0100 Subject: [PATCH 06/12] size check --- .size-limit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.size-limit.js b/.size-limit.js index 2a14a40df88b..361e2026f2c7 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -255,7 +255,7 @@ module.exports = [ path: createCDNPath('bundle.tracing.logs.metrics.min.js'), gzip: false, brotli: false, - limit: '130 KB', + limit: '131 KB', }, { name: 'CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed', From 4d8a9738d199c97b5b869eae5b4889b7d3926d0b Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 14:01:27 +0100 Subject: [PATCH 07/12] stop flushing too early --- packages/core/src/client.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index daff0bf728fa..a66fc99adcbf 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1149,10 +1149,6 @@ export abstract class Client { * `false` otherwise */ protected async _isClientDoneProcessing(timeout?: number): Promise { - if (!this._numProcessing) { - return true; - } - let ticked = 0; while (!timeout || ticked < timeout) { From 39baa2f5ea852ae5f04ba14e8bfbce010a0cefd6 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 17:49:45 +0100 Subject: [PATCH 08/12] Update packages/core/src/utils/timer.ts Co-authored-by: Charly Gomez --- packages/core/src/utils/timer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/utils/timer.ts b/packages/core/src/utils/timer.ts index f7d621ab8a6c..f08b698a8e67 100644 --- a/packages/core/src/utils/timer.ts +++ b/packages/core/src/utils/timer.ts @@ -1,7 +1,7 @@ /** * Calls `unref` on a timer, if the method is available on @param timer. * - * `unred()` is used to allow processes to exit immediately, even if the timer + * `unref()` is used to allow processes to exit immediately, even if the timer * is still running and hasn't resolved yet. * * Use this in places where code can run on browser or server, since browsers From 917fc69d13618e2ef462dcf1d9fbb973d8487ce0 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 17:50:13 +0100 Subject: [PATCH 09/12] make test more strict --- packages/core/test/lib/client.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index 572524143658..09ec34bf4fcc 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2207,18 +2207,24 @@ describe('Client', () => { }); test('flush returns immediately when nothing is processing', async () => { - vi.useRealTimers(); + vi.useFakeTimers(); expect.assertions(2); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); const client = new TestClient(options); - const startTime = Date.now(); - const result = await client.flush(1000); - const elapsed = Date.now() - startTime; + // just to ensure the client init'd + vi.advanceTimersByTime(100); + + const elapsed = Date.now(); + const done = client.flush(1000).then(result => { + expect(result).toBe(true); + expect(Date.now() - elapsed).toBeLessThan(2); + }); - expect(result).toBe(true); - expect(elapsed).toBeLessThan(100); + // ensures that only after 1 ms, we're already done flushing + vi.advanceTimersByTime(1); + await done; }); test('flush with early exit when processing completes', async () => { From 35ace6991ce5964a04f7fbdb832926b6327c6c2c Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 18:33:35 +0100 Subject: [PATCH 10/12] do not unref the 1ms delay --- packages/core/src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index a66fc99adcbf..f8b1bbfe707e 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1152,7 +1152,7 @@ export abstract class Client { let ticked = 0; while (!timeout || ticked < timeout) { - await new Promise(resolve => safeUnref(setTimeout(resolve, 1))); + await new Promise(resolve => setTimeout(resolve, 1)); if (!this._numProcessing) { return true; From 755abb376c5e169e231f115f872cb2b9e8c28a40 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 18:39:31 +0100 Subject: [PATCH 11/12] use safeUnref in offline transport --- packages/core/src/transports/offline.ts | 33 ++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/core/src/transports/offline.ts b/packages/core/src/transports/offline.ts index 88211a4378e7..b799bf691efb 100644 --- a/packages/core/src/transports/offline.ts +++ b/packages/core/src/transports/offline.ts @@ -4,6 +4,7 @@ import type { InternalBaseTransportOptions, Transport, TransportMakeRequestRespo import { debug } from '../utils/debug-logger'; import { envelopeContainsItemType } from '../utils/envelope'; import { parseRetryAfterHeader } from '../utils/ratelimit'; +import { safeUnref } from '../utils/timer'; export const MIN_DELAY = 100; // 100 ms export const START_DELAY = 5_000; // 5 seconds @@ -97,26 +98,24 @@ export function makeOfflineTransport( clearTimeout(flushTimer as ReturnType); } - flushTimer = setTimeout(async () => { - flushTimer = undefined; - - const found = await store.shift(); - if (found) { - log('Attempting to send previously queued event'); + // We need to unref the timer in node.js, otherwise the node process never exit. + flushTimer = safeUnref( + setTimeout(async () => { + flushTimer = undefined; - // We should to update the sent_at timestamp to the current time. - found[0].sent_at = new Date().toISOString(); + const found = await store.shift(); + if (found) { + log('Attempting to send previously queued event'); - void send(found, true).catch(e => { - log('Failed to retry sending', e); - }); - } - }, delay) as Timer; + // We should to update the sent_at timestamp to the current time. + found[0].sent_at = new Date().toISOString(); - // We need to unref the timer in node.js, otherwise the node process never exit. - if (typeof flushTimer !== 'number' && flushTimer.unref) { - flushTimer.unref(); - } + void send(found, true).catch(e => { + log('Failed to retry sending', e); + }); + } + }, delay), + ) as Timer; } function flushWithBackOff(): void { From d93d93cecaf4e8b67a987eae3325fbb84b1953e7 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Thu, 29 Jan 2026 18:51:16 +0100 Subject: [PATCH 12/12] lint --- packages/core/src/client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index f8b1bbfe707e..1ed447ab802d 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -49,7 +49,6 @@ import { safeMathRandom } from './utils/randomSafeContext'; import { reparentChildSpans, shouldIgnoreSpan } from './utils/should-ignore-span'; import { showSpanDropWarning } from './utils/spanUtils'; import { rejectedSyncPromise } from './utils/syncpromise'; -import { safeUnref } from './utils/timer'; import { convertSpanJsonToTransactionEvent, convertTransactionEventToSpanJson } from './utils/transactionEvent'; const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";