使用Puppeteer时Node.js的SIGINT事件未按预期工作
问题解决方法
核心原因
Puppeteer初始化后,Node.js进程收到SIGINT/SIGTERM/SIGQUIT时,默认的退出行为会优先触发,导致上报逻辑的Promise还未完成,进程就已经终止。同时Puppeteer启动的Chrome子进程可能会传递额外信号,加速主进程退出。
修复步骤
1. 阻止默认信号退出,等待上报完成
修改信号处理逻辑,先移除对应信号的默认监听器,避免进程立即退出,同时处理上报请求的异常情况:
async function handleQuit(signal) { // 移除当前信号的默认监听器,防止进程直接退出 process.removeAllListeners(signal); try { // 批量执行上报请求 await Promise.all(requests.map(id => steps.report({id}, 'worker.closed', 'error', 'process closed') )); // 若存在Puppeteer浏览器实例,可在此先关闭(按需添加) // if (browser) await browser.close(); process.exit(0); } catch (err) { console.error('上报失败:', err); process.exit(1); } } process.on('SIGINT', handleQuit); process.on('SIGTERM', handleQuit); process.on('SIGQUIT', handleQuit);
2. 配置Puppeteer忽略信号(可选)
如果Chrome子进程的信号处理干扰主进程,启动Puppeteer时可添加参数让Chrome不处理信号,交给主进程统一处理:
const browser = await puppeteer.launch({ args: [ '--no-sandbox', '--disable-setuid-sandbox', // 禁用Chrome自身的信号处理逻辑 '--disable-signal-handling' ] });
关键说明
- 用
async/await替代Promise链式调用,代码更简洁且能捕获异常。 - 移除信号默认监听器是核心操作,确保进程能等待上报完成后再退出。
- 必须处理
Promise.all的异常,避免上报失败时进程挂起无法正常退出。
内容的提问来源于stack exchange,提问作者Pezhvak
相关产品推荐
相关产品推荐

