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

Node.js Async/Await中return语句返回结果异常问题排查

问题:DynamoDB查询返回空对象但日志能输出正确数据

我在写DynamoDB查询代码,同时学习Promise相关知识。console.log(resp.Items)能打印出预期的对象,说明查询格式没问题,但接口返回200状态码时却带空对象。查了资料改了好几次代码,还是没法返回resp.Items,猜可能函数在拿到数据前就返回了,但搞不懂为啥日志能正常输出。

相关代码

getTechs 函数

const AWS = require('aws-sdk')
const dynamodb = new AWS.DynamoDB()

const getTechs = async () => {
  try {
    const resp = await dynamodb
      .query({
        ExpressionAttributeValues: {
          ':tech': { S: 'TECH#' },
        },
        KeyConditionExpression: 'PK = :tech',
        TableName: process.env.TABLE_NAME,
        ScanIndexForward: true,
      })
      .promise()
    console.log(resp.Items)

    if (!resp.Items) {
      return {
        error: 'No Techs in the DB',
      }
    }
    
    return {
      tech: resp.Items,
    }

  } catch (error) {
    console.log('Error retrieving Tech List')
    console.log(error)
    return {
      error: 'Could not retrieve Tech List',
    }
  }
}

Handler 函数

const { makeHandler } = require('./utils')
const { getTechs } = require('../data')
// const { Tech } = require('../entities')

const inputSchema = {
  type: 'object',
  properties: {
    pathParameters: {
      type: 'object',
      properties: {
        tech: { type: 'string' },
      },
      required: ['tech'],
    },
  },
  required: ['pathParameters'],
}

const handler = async (event) => {
  const { techs, error } = await getTechs()
  const statusCode = error ? 500 : 200
  const body = error ? JSON.stringify({ error }) : JSON.stringify({ techs })
  return {
    statusCode,
    body,
  }
}

module.exports.handler = makeHandler({ handler })

executeTransactWrite 函数

const executeTransactWrite = async ({ tech, params }) => {
  const transactionRequest = tech.transactWriteItems(params)
  let cancellationReasons
  transactionRequest.on('extractError', (response) => {
    try {
      cancellationReasons = JSON.parse(
        response.httpResponse.body.toString()
      ).CancellationReasons
    } catch (err) {
      // suppress this just in case some types of errors aren't JSON parseable
      console.error('Error extracting cancellation error', err)
    }
  })
  return new Promise((resolve, reject) => {
    transactionRequest.send((err, response) => {
      if (err) {
        err.cancellationReasons = cancellationReasons
        return reject(err)
      }
      return resolve(response)
    })
  })
}

module.exports = {
  executeTransactWrite,
}

makeHandler 函数

const middy = require('middy')
const {
  jsonBodyParser,
  validator,
  httpErrorHandler,
} = require('middy/middlewares')

const makeHandler = ({ handler, inputSchema }) =>
  middy(handler)
    .use(jsonBodyParser())
    .use(validator({ inputSchema }))
    .use(httpErrorHandler())

module.exports = { makeHandler }

问题原因及修复

核心问题是变量名不匹配:

  • getTechs函数返回的对象键是tech,但handler里解构时用的是techs,导致techs为undefined,经过JSON.stringify后就变成了空对象{}。

有两种修复方式:

  1. 修改getTechs的返回值,把键名改成techs:
return {
  techs: resp.Items,
}
  1. 修改handler中的解构和后续代码,匹配getTechs返回的键名:
const { tech, error } = await getTechs()
const body = error ? JSON.stringify({ error }) : JSON.stringify({ tech })

另外还有一个潜在问题:inputSchema要求请求必须携带pathParameters.tech字段,但getTechs函数完全没用到这个参数。如果接口是要根据路径参数查询特定技术项,那getTechs需要接收参数并修改DynamoDB的查询条件;如果不需要这个参数,就删掉inputSchema里的对应校验规则,否则请求会因为参数校验失败被拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:25:39