Is there an existing issue for this?
How do you use Sentry?
Sentry SaaS (sentry.io)
Which SDK are you using?
@sentry/node
SDK Version
10.36.0
Framework Version
Bun 1.3.3 / Node.js 22
Link to Sentry event
No response
Reproduction Example/SDK Setup
import*asSentryfrom"@sentry/node";constclient=Sentry.init({dsn: "https://your-dsn@sentry.io/123",enabled: true,defaultIntegrations: false,});// This will block for 3 seconds even when there's nothing to sendawaitclient?.flush(3000);Steps to Reproduce
- Initialize Sentry in a CLI application
- Call
client.flush(3000) before exiting - Observe the process hangs for ~3 seconds even when there's nothing to flush
Expected Result
flush(timeout) should:
- Return immediately if there's nothing to process (
_numProcessing === 0) - Use
unref() on internal timers so the process can exit naturally when work is complete
Actual Result
The process blocks for the full timeout duration because:
_isClientDoneProcessing() in client.js checks _numProcessingafter the first setTimeout, not before:
async_isClientDoneProcessing(timeout){letticked=0;while(!timeout||ticked<timeout){awaitnewPromise(resolve=>setTimeout(resolve,1));// Always waits firstif(!this._numProcessing){returntrue;}ticked++;}returnfalse;}The setTimeout calls don't use .unref(), keeping the Node.js event loop alive:
client.js line 650: setTimeout(resolve, 1) - polling looppromisebuffer.js line 72: setTimeout(() => resolve(false), timeout) - drain timeout
Other parts of the codebase already use .unref() correctly (e.g., httpServerIntegration.js line 234).
Suggested Fix
Add early exit check in _isClientDoneProcessing():
async_isClientDoneProcessing(timeout){if(!this._numProcessing){returntrue;// Early exit}// ... rest of polling loop}Add .unref() to timers with browser-safe check:
awaitnewPromise(resolve=>{constt=setTimeout(resolve,1);if(typeoft!=='number'&&t.unref)t.unref();});
Is there an existing issue for this?
How do you use Sentry?
Sentry SaaS (sentry.io)
Which SDK are you using?
@sentry/nodeSDK Version
10.36.0
Framework Version
Bun 1.3.3 / Node.js 22
Link to Sentry event
No response
Reproduction Example/SDK Setup
Steps to Reproduce
client.flush(3000)before exitingExpected Result
flush(timeout)should:_numProcessing === 0)unref()on internal timers so the process can exit naturally when work is completeActual Result
The process blocks for the full timeout duration because:
_isClientDoneProcessing()inclient.jschecks_numProcessingafter the firstsetTimeout, not before:The
setTimeoutcalls don't use.unref(), keeping the Node.js event loop alive:client.jsline 650:setTimeout(resolve, 1)- polling looppromisebuffer.jsline 72:setTimeout(() => resolve(false), timeout)- drain timeoutOther parts of the codebase already use
.unref()correctly (e.g.,httpServerIntegration.jsline 234).Suggested Fix
Add early exit check in
_isClientDoneProcessing():Add
.unref()to timers with browser-safe check: