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

AWS Lambda中s3.putObject()上传成功却无返回的问题排查

问题描述

我们在AWS Lambda函数中运行以下上传文件至AWS S3的代码:

import AWS from 'aws-sdk';
const s3 = new AWS.S3();

export async function putObjectToS3(
  data: any,
  nameOfFile: string,
  contentType: string
) {
  const params = {
    Bucket: process.env.S3_BUCKET || '',
    ContentType: contentType,
    Key: `${nameOfFile}`,
    Body: data
  };

  console.log('start s3 put object');
  const response = await s3.putObject(params).promise();

  console.log('end s3 put object: ', response);
  return response;
}


await putObjectToS3(artistsCsv, `artists/artists.csv`, 'text/csv');

目前artistsCsv文件已成功上传至S3(可在S3中看到该CSV文件),但函数始终无法返回。日志中仅能看到start s3 put object,却从未出现end s3 put object: , response。

使用的aws-sdk版本为^2.1147.0,请问:

  1. 函数写法是否存在问题导致无法返回response?
  2. 是否可能是AWS自身问题?
  3. 或是在.promise()与async/await的使用上存在疏漏?
  4. 该如何排查此问题?

分析与解决方案

1. 函数写法的潜在问题

  • Lambda入口处理疏漏:直接在顶层使用await putObjectToS3(...)是核心问题之一。Lambda的初始化阶段与执行阶段分离,顶层代码在初始化时运行,而handler才是执行阶段的入口。如果异步调用不在handler内部,Lambda可能在异步操作完成前就终止执行环境,导致后续日志和返回逻辑无法触发。
  • Bucket参数校验缺失:process.env.S3_BUCKET || ''在环境变量未配置时会传入空Bucket名,但当前上传成功说明Bucket有效,可后续添加参数校验避免异常。

2. AWS自身问题的可能性

可能性极低。文件已成功上传,说明s3.putObject的核心操作已完成。若AWS服务端异常,通常会返回明确错误而非静默无日志。可做两点验证:

  • 检查CloudWatch Logs是否存在日志截断情况;
  • 通过S3控制台查看文件元数据中的请求ID,如有企业支持计划,可在AWS Support中查询请求异常记录。

3. .promise()与async/await的使用是否有疏漏

代码中await s3.putObject(params).promise()的写法符合aws-sdk v2的规范,没有疏漏。但如果artistsCsv是可读流,存在流未正确关闭导致事件循环未清空的可能——不过文件已上传成功,流应该已被消费完成,可后续转换为Buffer验证。

4. 排查步骤

  • 将调用移入Lambda Handler:把异步操作包裹在handler函数内,确保执行流程被Lambda正确管控:
    export const handler = async () => {
      try {
        await putObjectToS3(artistsCsv, `artists/artists.csv`, 'text/csv');
        return { statusCode: 200, body: 'Upload completed' };
      } catch (err) {
        console.error('Handler error:', err);
        return { statusCode: 500, body: 'Upload failed' };
      }
    };
    
  • 添加错误捕获:在putObjectToS3中加入try/catch,避免异常被静默吞掉:
    export async function putObjectToS3(
      data: any,
      nameOfFile: string,
      contentType: string
    ) {
      try {
        const params = {
          Bucket: process.env.S3_BUCKET || '',
          ContentType: contentType,
          Key: `${nameOfFile}`,
          Body: data
        };
    
        console.log('start s3 put object');
        const response = await s3.putObject(params).promise();
    
        console.log('end s3 put object: ', response);
        return response;
      } catch (err) {
        console.error('S3 upload error:', err);
        throw err;
      }
    }
    
  • 调整Lambda超时时间:默认3秒超时可能导致后续日志打印和返回逻辑来不及执行,可暂时延长至10秒测试。
  • 验证artistsCsv类型:若artistsCsv是流对象,转换为Buffer后再上传验证:
    const buffer = await new Promise((resolve, reject) => {
      const chunks: Uint8Array[] = [];
      artistsCsv.on('data', chunk => chunks.push(chunk));
      artistsCsv.on('end', () => resolve(Buffer.concat(chunks)));
      artistsCsv.on('error', reject);
    });
    await putObjectToS3(buffer, `artists/artists.csv`, 'text/csv');
    
  • 检查Lambda执行角色权限:确保角色拥有logs:CreateLogStream和logs:PutLogEvents权限,避免日志无法写入CloudWatch导致看不到后续输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:17:22