Node.js Lambda脚本中process.exit提前执行致traceroute无输出的解决方法
问题原因
你的问题核心在于doTraceroute函数没有正确实现异步等待逻辑:nodejs-traceroute是基于事件驱动的,调用tracer.trace()后会立即返回,后续的hop、close等事件都是异步触发的。但你当前的doTraceroute没有返回Promise,导致await doTraceroute()根本没等traceroute执行完成,就直接走到了process.exit(1)这一步,把还在运行的traceroute进程强制终止了,自然看不到完整输出。
解决方案
我们需要把doTraceroute改造成返回Promise的函数,让它在traceroute的close事件触发后再resolve,这样await就能正确等待整个追踪流程完成。同时,在Lambda环境下更推荐用官方的回调函数处理退出,而非直接调用process.exit,避免异常终止导致的日志丢失。
修改后的完整代码如下:
'use strict'; const Traceroute = require('nodejs-traceroute'); const isPortReachable = require('is-port-reachable'); console.log('Loading function'); process.env.PATH = `${process.env.PATH}:${process.env.LAMBDA_TASK_ROOT}/bin`; // 改造为返回Promise的异步函数,确保能被await正确等待 async function doTraceroute() { return new Promise((resolve, reject) => { try { const tracer = new Traceroute(); tracer .on('pid', (pid) => { console.log(`pid: ${pid}`); }) .on('destination', (destination) => { console.log(`destination: ${destination}`); }) .on('hop', (hop) => { console.log(`hop: ${JSON.stringify(hop)}`); }) .on('close', (code) => { console.log(`close: code ${code}`); resolve(code); // traceroute完成后resolve Promise }) .on('error', (err) => { console.log(`traceroute error: ${err}`); reject(err); // 捕获traceroute的错误并reject }); tracer.trace('100.216.125.9'); } catch (ex) { console.log(ex); reject(ex); } }); } exports.handler = (event, context, callback) => { (async () => { console.log('Is port 9092 reachable of MC Kafka host? True or False') let output = await isPortReachable(9092, {host: '100.216.125.9'}) if (output) { console.log('Telnet worked: do traceroute') await doTraceroute(); callback(null, 'Port reachable, traceroute completed'); // Lambda正常退出回调 } else { console.log('Telnet failed: do traceroute') await doTraceroute(); // 现在会完整等待traceroute执行完毕 console.log("Exit with error") callback(new Error('Port unreachable after traceroute')); // Lambda错误退出回调 // 若坚持用process.exit,需放在await之后: // process.exit(1); } })().catch(err => { console.error('Unhandled error:', err); callback(err); }); };
关键改动说明
- Promise包装事件流:用Promise包裹traceroute的整个生命周期,在
close事件触发时resolve,确保await能等待所有追踪日志输出完成。 - 完善错误处理:新增
error事件监听,捕获traceroute过程中的异常并通过Promise reject抛出,避免未捕获的错误导致Lambda意外终止。 - Lambda规范退出:使用Lambda官方的
callback函数处理成功/失败状态,比直接调用process.exit更符合Runtime规范,能保证所有日志被正确收集。
这样修改后,无论端口检测成功还是失败,traceroute的完整输出都会被打印,之后才会执行退出逻辑。
内容的提问来源于stack exchange,提问作者DenCowboy
相关产品推荐
相关产品推荐

