You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
  });
};
关键改动说明
  1. Promise包装事件流:用Promise包裹traceroute的整个生命周期,在close事件触发时resolve,确保await能等待所有追踪日志输出完成。
  2. 完善错误处理:新增error事件监听,捕获traceroute过程中的异常并通过Promise reject抛出,避免未捕获的错误导致Lambda意外终止。
  3. Lambda规范退出:使用Lambda官方的callback函数处理成功/失败状态,比直接调用process.exit更符合Runtime规范,能保证所有日志被正确收集。

这样修改后,无论端口检测成功还是失败,traceroute的完整输出都会被打印,之后才会执行退出逻辑。

内容的提问来源于stack exchange,提问作者DenCowboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:07:27