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

AWS Lambda中JSON.stringify循环引用错误排查与修复

问题:AWS Lambda中JSON.stringify循环结构错误排查与修复

在AWS Lambda函数运行代码时,出现TypeError: Converting circular structure to JSON错误,错误指向MessageBody: JSON.stringify(messageBody)行,需排查循环结构位置并修改SQS消息结构解决问题。

运行代码

const addRanksToDB = async (tableName, stats) => {
  return Promise.all(Object.keys(stats).map(async (slug) => {
    const projectSlug = slug;
    const rankData = stats[slug];

    const messageBody = {
      rowId: projectSlug,
      table: tableName,
      identifier: 'project_slug',
      action: 'insert',
      payload: {
        project_slug: projectSlug,
        ...rankData,
        last_updated: knexClient.fn.now(),
      },
    };

    return sqs.sendMessage({
      MessageBody: JSON.stringify(messageBody),
      QueueUrl: 'https://sqs.eu-central-1.amazonaws.com/599632852002/handleDataInDBQueue',
    }).promise();
  }));
};

rankData结构

{
  one_day_volume: 191,
  seven_day_volume: 162,
  thirty_day_volume: 179,
  total_volume: 156,
  num_owners: 4,
  average_price: 129,
  market_cap: 66,
  floor_price: 146
}

错误信息

{
    "errorType": "TypeError",
    "errorMessage": "Converting circular structure to JSON\n    --> starting at object with constructor 'Timeout'\n    |     property '_idlePrev' -> object with constructor 'TimersList'\n    --- property '_idleNext' closes the circle",
    "trace": [
        "TypeError: Converting circular structure to JSON",
        "    --> starting at object with constructor 'Timeout'",
        "    |     property '_idlePrev' -> object with constructor 'TimersList'",
        "    --- property '_idleNext' closes the circle",
        "    at JSON.stringify (<anonymous>)",
        "    at /var/task/src/handlers/stats/webpack:/handlers/stats/rankProjectsByStatsCronjob.js:84:27",
        "    at Array.map (<anonymous>)",
        "    at v (/var/task/src/handlers/stats/webpack:/handlers/stats/rankProjectsByStatsCronjob.js:67:43)",
        "    at Runtime.R [as handler] (/var/task/src/handlers/stats/webpack:/handlers/stats/rankProjectsByStatsCronjob.js:188:23)",
        "    at processTicksAndRejections (internal/process/task_queues.js:95:5)"
    ]
}

问题根源与修复方案

问题根源

错误提示中的循环引用来自knexClient.fn.now()——这个方法返回的不是原始日期字符串或时间戳,而是Knex内部的查询构建对象,包含Timeout、TimersList这类带有循环引用的属性,无法被JSON.stringify序列化。

修复方案

有两种可行的修改方式:

方式1:传递客户端侧的当前时间

将knexClient.fn.now()替换为可序列化的日期值,比如ISO格式字符串:

const messageBody = {
  rowId: projectSlug,
  table: tableName,
  identifier: 'project_slug',
  action: 'insert',
  payload: {
    project_slug: projectSlug,
    ...rankData,
    last_updated: new Date().toISOString(), // 替换为客户端当前时间
  },
};

方式2:在消费端生成数据库时间

如果需要使用数据库服务器的当前时间,不要在消息体中传递Knex函数对象,而是传递一个标记,在SQS消息的消费处理函数中再替换为knexClient.fn.now():

  1. 发送消息时修改payload:
payload: {
  project_slug: projectSlug,
  ...rankData,
  last_updated: 'USE_DB_NOW', // 用标记代替函数对象
},
  1. 在消费SQS消息的数据库处理代码中:
// 假设消费端处理逻辑
const handleDBInsert = async (payload) => {
  const insertData = {
    ...payload,
    last_updated: payload.last_updated === 'USE_DB_NOW' ? knexClient.fn.now() : payload.last_updated,
  };
  // 执行数据库插入操作
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:06:22