Skip to content

fix(core): drain buffers in flush() when there is no transport#20207

Open
sbs44 wants to merge 1 commit intogetsentry:developfrom
sbs44:fix/flush-buffers-without-transport
Open

fix(core): drain buffers in flush() when there is no transport#20207
sbs44 wants to merge 1 commit intogetsentry:developfrom
sbs44:fix/flush-buffers-without-transport

Conversation

@sbs44
Copy link
Copy Markdown

@sbs44 sbs44 commented Apr 10, 2026

Client.flush() short-circuited before emitting the 'flush' event when the client had no transport (e.g. no DSN was configured), leaving the weight-based flushers for logs and metrics with idle setTimeout handles that never resolved. Move emit('flush') above the !transport early return so the setupWeightBasedFlushing listeners on 'flushLogs' / 'flushMetrics' drain their buffers and clear the idle timer on every flush() call.

We originally hit this in Supabase Deno edge function tests where a shared harness calls Sentry.init({ dsn: '', enableLogs: true }) and records metrics per request, then calls Sentry.flush(2000) in the request finalizer. The Deno test sanitizer surfaces the unresolved setTimeout as a leaked op:

error: Leaks detected:
  - 2 timers were started in this test, but never completed.
    at setTimeout (node:timers:14:10)
    at .../@sentry/core/10.48.0/build/esm/client.js:108:9
    at DenoClient.emit (.../@sentry/core/10.48.0/build/esm/client.js:572:17)

Behavior change

Any subscriber registered via client.on('flush', …) will now fire when flush() is called on a transport-less client. I verified the in-repo subscribers all handle this safely:

  • setupWeightBasedFlushing_INTERNAL_flushLogsBuffer / _INTERNAL_flushMetricsBuffer --> client.sendEnvelope, which short-circuits on !this._transport (client.ts:1139)
  • SpanBuffer.drain() (spanBuffer.ts:86) — builds envelopes and hands them to the same sendEnvelope guard
  • httpServerIntegration --> flushPendingClientAggregates --> client.sendSession... also routed through sendEnvelope
  • otlpIntegration --> _spanProcessor?.forceFlush(): OTLP has its own exporter independent of the Sentry transport

Integration authors with custom 'flush' listeners that previously assumed a transport was present may want to audit their handlers.

Tests

Added two regression tests (one for logs, one for metrics) that fail on develop and pass with the fix. Both assert the observable end state (the buffer is drained via 'flushLogs' / 'flushMetrics') rather than relying on an indirect clearTimeout spy.

Before submitting a pull request, please take a look at our
Contributing guidelines and verify:

  • If you've added code that should be tested, please add tests.
  • Ensure your code lints and the test suite passes (yarn lint) & (yarn test).
  • Link an issue if there is one related to your pull request. If no issue is linked, one will be auto-generated and linked.

Closes #20206

…transport

`Client.flush()` short-circuited before emitting the `flush` event when
the client had no transport (e.g. no DSN was configured), leaving the
weight-based flushers for logs and metrics with idle `setTimeout`
handles that never resolved. Emit `flush` unconditionally so the
weight-based flusher listeners drain their buffers and clear the timers
on every `flush()` call.
@sdk-maintainer-bot sdk-maintainer-bot bot added missing-maintainer-discussion Used for automated community contribution checks. violating-contribution-guidelines Used for automated community contribution checks. labels Apr 10, 2026
@sdk-maintainer-bot
Copy link
Copy Markdown

This PR has been automatically closed. The referenced issue does not show a discussion between you and a maintainer.

To avoid wasted effort on both sides, please discuss your proposed approach in the issue first and wait for a maintainer to respond before opening a PR.

Please review our contributing guidelines for more details.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Core

  • Add enableTruncation option to Google GenAI integration by andreiborza in #20184
  • Add enableTruncation option to Anthropic AI integration by andreiborza in #20181
  • Add enableTruncation option to LangGraph integration by andreiborza in #20183
  • Add enableTruncation option to LangChain integration by andreiborza in #20182
  • Add enableTruncation option to OpenAI integration by andreiborza in #20167
  • Export a reusable function to add tracing headers by JPeer264 in #20076

Deps

  • Bump axios from 1.13.5 to 1.15.0 by dependabot in #20180
  • Bump hono from 4.12.7 to 4.12.12 by dependabot in #20118
  • Bump defu from 6.1.4 to 6.1.6 by dependabot in #20104

Other

  • (cloudflare) Propagate traceparent to RPC calls - via fetch by JPeer264 in #19991

Bug Fixes 🐛

Deno

  • Handle reader.closed rejection from releaseLock() in streaming by andreiborza in #20187
  • Avoid inferring invalid span op from Deno tracer by Lms24 in #20128

Other

  • (ci) Prevent command injection in ci-metadata workflow by fix-it-felix-sentry in #19899
  • (core) Drain buffers in flush() when there is no transport by sbs44 in #20207
  • (e2e) Add op check to waitForTransaction in React Router e2e tests by copilot-swe-agent in #20193
  • (node-integration-tests) Fix flaky kafkajs test race condition by copilot-swe-agent in #20189

Internal Changes 🔧

Deps

  • Bump hono from 4.12.7 to 4.12.12 in /dev-packages/e2e-tests/test-applications/cloudflare-hono by dependabot in #20119
  • Bump axios from 1.13.5 to 1.15.0 in /dev-packages/e2e-tests/test-applications/nestjs-basic by dependabot in #20179

Other

  • (bugbot) Add rules to flag test-flake-provoking patterns by Lms24 in #20192
  • (deps-dev) Bump vite from 7.2.0 to 7.3.2 in /dev-packages/e2e-tests/test-applications/tanstackstart-react by dependabot in #20107
  • (react) Remove duplicated test mock by s1gr1d in #20200
  • (size-limit) Bump failing size limit scenario by Lms24 in #20186
  • Add automatic flaky test detector by nicohrubec in #18684

🤖 This preview updates automatically when you update the PR.

@JPeer264 JPeer264 reopened this Apr 13, 2026
@JPeer264 JPeer264 removed violating-contribution-guidelines Used for automated community contribution checks. missing-maintainer-discussion Used for automated community contribution checks. labels Apr 13, 2026
Copy link
Copy Markdown
Member

@JPeer264 JPeer264 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for contributing. This fix looks very legitimate - I also took a look on previous PRs moving/adding this hook, it seems that this is something we never considered, but it makes perfect sense this way.

@JPeer264 JPeer264 requested a review from s1gr1d April 13, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Client.flush() leaks log/metric flush timers when client has no transport

2 participants