为何Promise无返回?求助Lambda函数S3上传代码异常问题
排查Lambda Promise无返回的问题
看起来你的Lambda函数里的Promise一直处于pending状态,导致没有返回值,我帮你梳理几个关键问题和修复方案:
核心问题分析
Promise内部错误未传递
你在Promise内部的try-catch块里捕获了错误,但只打印了日志却没有调用reject(error)——这会导致Promise永远卡在pending状态,then或catch回调永远不会触发,Lambda会一直等待callback调用,最终超时。未声明的关键变量
代码里用到了bucketName和s3,但没看到它们的定义:s3需要是AWS.S3的实例(比如const s3 = new AWS.S3();)bucketName是你的S3存储桶名称
如果这些变量未定义,会直接抛出ReferenceError,中断代码执行。
同步代码错误未被妥善处理
params对象的创建在Promise内部的try块之外,如果event.pathParameters.hospital不存在或者bucketName未定义,会直接抛出错误,虽然这个错误会让Promise拒绝,但最好把这些逻辑也放进try块统一处理。async函数与callback混用
你的函数声明为async,却用callback返回响应,这不是最佳实践,async函数可以直接return响应对象,Lambda会自动处理。
修复后的代码
我把你的代码重构了一下,解决了这些问题,同时用AWS SDK自带的.promise()方法替代手动封装Promise,更简洁可靠:
// 引入AWS SDK并初始化S3实例 const AWS = require('aws-sdk'); const s3 = new AWS.S3(); // 替换成你的实际存储桶名称 const bucketName = 'your-actual-bucket-name'; exports.FilelamdaFunctionHandler = async function(event) { try { // 先校验必要参数是否存在 if (!event.pathParameters?.hospital) { return { statusCode: 400, body: JSON.stringify({ error: 'Missing required "hospital" parameter' }) }; } const contentType = event.headers['Content-Type']; console.log('content type is--' + contentType); // 安全处理Content-Type拆分,避免undefined报错 const contentTypeParts = contentType?.split("/") || []; const fileExtension = (contentTypeParts[1] === 'plain') ? ".txt" : ".csv"; const params = { Body: event.body, Bucket: `${bucketName}/${event.pathParameters.hospital}`, Key: `${event.pathParameters.hospital}${fileExtension}`, // 设置正确的Content-Type,而不是通配符"*" ContentType: contentType || 'text/plain' }; // 使用S3的promise版本,直接await获取结果 const uploadResult = await s3.putObject(params).promise(); console.log('Upload result --' + JSON.stringify(uploadResult)); return { statusCode: 200, body: JSON.stringify({ message: "File uploaded successfully" }) }; } catch (error) { console.log('Error during upload:', error.toString()); console.log('Error details:', JSON.stringify(error)); return { statusCode: 500, body: JSON.stringify({ error: "Failed to upload file to S3" }) }; } };
关键修复点说明
- 移除手动Promise封装:AWS SDK的方法都支持
.promise(),用await调用更直观,避免手动处理回调和Promise状态的错误。 - 统一错误处理:所有同步和异步错误都会被外层
try-catch捕获,确保Lambda能返回错误响应,不会超时。 - 添加参数校验:提前检查
hospital参数,避免后续拼接路径时出错。 - 安全处理Content-Type:防止
contentType为undefined时split方法报错。 - 使用async/await替代callback:符合Lambda async函数的最佳实践,代码更易读维护。
内容的提问来源于stack exchange,提问作者praveen
相关产品推荐
相关产品推荐

