Skip to content

Commit 97350fd

Browse files
committed
Ensure Ctrl+C exit does not wait indefinitely
1 parent e1d494c commit 97350fd

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

cli/src/hooks/use-exit-handler.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ export const useExitHandler = ({
5959
process.exit(0)
6060
}, [])
6161

62+
const flushAnalyticsWithTimeout = useCallback(async (timeoutMs = 1000) => {
63+
try {
64+
const flushPromise = flushAnalytics()
65+
if (!flushPromise || typeof (flushPromise as Promise<unknown>).finally !== 'function') {
66+
return
67+
}
68+
69+
await Promise.race([
70+
flushPromise as Promise<unknown>,
71+
new Promise((resolve) => setTimeout(resolve, timeoutMs)),
72+
])
73+
} catch {
74+
// Ignore flush failures and proceed with exit
75+
}
76+
}, [])
77+
78+
const exitAfterFlush = useCallback(() => {
79+
void (async () => {
80+
await flushAnalyticsWithTimeout()
81+
exitNow()
82+
})()
83+
}, [exitNow, flushAnalyticsWithTimeout])
84+
6285
const handleCtrlC = useCallback(() => {
6386
if (inputValue) {
6487
setInputValue({ text: '', cursorPosition: 0, lastEditDueToNav: false })
@@ -74,32 +97,20 @@ export const useExitHandler = ({
7497
return true
7598
}
7699

77-
const flushed = flushAnalytics()
78-
if (flushed && typeof (flushed as Promise<void>).finally === 'function') {
79-
const flushPromise = flushed as Promise<void>
80-
flushPromise.finally(exitNow)
81-
} else {
82-
exitNow()
83-
}
100+
exitAfterFlush()
84101
return true
85-
}, [exitNow, inputValue, setInputValue, nextCtrlCWillExit])
102+
}, [exitAfterFlush, inputValue, setInputValue, nextCtrlCWillExit])
86103

87104
useEffect(() => {
88105
const handleSigint = () => {
89-
const flushed = flushAnalytics()
90-
if (flushed && typeof (flushed as Promise<void>).finally === 'function') {
91-
const flushPromise = flushed as Promise<void>
92-
flushPromise.finally(exitNow)
93-
} else {
94-
exitNow()
95-
}
106+
exitAfterFlush()
96107
}
97108

98109
process.on('SIGINT', handleSigint)
99110
return () => {
100111
process.off('SIGINT', handleSigint)
101112
}
102-
}, [])
113+
}, [exitAfterFlush])
103114

104115
return { handleCtrlC, nextCtrlCWillExit }
105116
}

0 commit comments

Comments
 (0)