fix(core): drain buffers in flush() when there is no transport#20207
fix(core): drain buffers in flush() when there is no transport#20207sbs44 wants to merge 1 commit intogetsentry:developfrom
Conversation
…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.
|
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. |
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Core
Deps
Other
Bug Fixes 🐛Deno
Other
Internal Changes 🔧Deps
Other
🤖 This preview updates automatically when you update the PR. |
JPeer264
left a comment
There was a problem hiding this comment.
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.
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 idlesetTimeouthandles that never resolved. Moveemit('flush')above the!transportearly return so thesetupWeightBasedFlushinglisteners on'flushLogs'/'flushMetrics'drain their buffers and clear the idle timer on everyflush()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 callsSentry.flush(2000)in the request finalizer. The Deno test sanitizer surfaces the unresolvedsetTimeoutas a leaked op:Behavior change
Any subscriber registered via
client.on('flush', …)will now fire whenflush()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 samesendEnvelopeguardhttpServerIntegration-->flushPendingClientAggregates-->client.sendSession... also routed throughsendEnvelopeotlpIntegration-->_spanProcessor?.forceFlush(): OTLP has its own exporter independent of the Sentry transportIntegration 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
developand pass with the fix. Both assert the observable end state (the buffer is drained via'flushLogs'/'flushMetrics') rather than relying on an indirectclearTimeoutspy.Before submitting a pull request, please take a look at our
Contributing guidelines and verify:
yarn lint) & (yarn test).Closes #20206