Lambda环境下执行S3客户端操作时如何获取错误日志?
问题现象
- Lambda函数执行到
console.log('Getting already imported files list...');代码行后无任何日志输出,直接触发超时,当前示例配置的超时时间为30秒 - 测试时故意指定了不存在的存储桶
testbucket,运行过程中既未输出错误消息,也无其他日志信息,需要开启相关日志输出定位问题
复现代码
import { ListObjectsV2Command, S3Client } from '@aws-sdk/client-s3'; export const handler = async (): Promise<unknown> => { try { const s3Client = new S3Client({ region: 'eu-west-3', logger: { error: (...messages: string[]): void => console.log(...messages), warn: (...messages: string[]): void => console.log(...messages), info: (...messages: string[]): void => console.log(...messages), debug: (...messages: string[]): void => console.log(...messages), }, maxAttempts: 1, }); console.log('Getting already imported files list...'); const res = await s3Client.send( new ListObjectsV2Command({ Bucket: 'testbucket', }), ); console.log({ res }); console.log('Ended :)'); return { statusCode: 200, message: 'ok?', }; } catch (error) { console.log('Error caught...'); console.log(error); return { statusCode: 500, message: 'Internal server error.', }; } };
根因说明
出现无日志直接超时的核心原因是AWS SDK for JavaScript v3 默认没有配置请求超时阈值,当Lambda到S3的网络链路不通时,SDK发起的请求会一直处于挂起等待状态,既不会触发错误抛出,也不会进入重试逻辑,直到Lambda达到配置的超时时间被强制终止,自然不会输出后续的业务日志和catch块的错误日志。
你代码里配置的maxAttempts: 1仅控制请求失败后的重试次数,不会限制单次请求的最长等待时间。
解决步骤
- 给S3客户端显式配置请求超时,避免请求无限挂起。AWS SDK v3需要通过
requestHandler传入自定义的HTTP Agent设置超时,修改后的代码如下:
import { ListObjectsV2Command, S3Client } from '@aws-sdk/client-s3'; import { NodeHttpHandler } from '@aws-sdk/node-http-handler'; import { Agent } from 'http'; import { Agent as HttpsAgent } from 'https'; export const handler = async (): Promise<unknown> => { try { const s3Client = new S3Client({ region: 'eu-west-3', // 配置请求超时:连接超时5秒,socket超时10秒 requestHandler: new NodeHttpHandler({ httpAgent: new Agent({ connectTimeout: 5000, timeout: 10000 }), httpsAgent: new HttpsAgent({ connectTimeout: 5000, timeout: 10000 }), }), logger: console, // 原生console已经实现了SDK要求的日志接口,无需手动封装 maxAttempts: 1, }); console.log('Getting already imported files list...'); const res = await s3Client.send( new ListObjectsV2Command({ Bucket: 'testbucket', }), ); console.log({ res }); console.log('Ended :)'); return { statusCode: 200, message: 'ok?', }; } catch (error) { console.log('Error caught...'); console.log(error); return { statusCode: 500, message: 'Internal server error.', }; } };
- 重新执行函数即可拿到明确的错误日志:
- 如果网络链路正常,会直接抛出
NoSuchBucket错误,提示指定的存储桶不存在 - 如果抛出连接超时错误,说明Lambda到S3的网络不通,需要进一步排查网络配置:
- 未配置VPC的Lambda:检查执行角色是否有S3访问权限、关联的安全组是否允许443端口出站流量
- 配置了VPC的Lambda:确认子网是否配置了指向NAT网关或S3 VPC终端节点的路由规则,安全组是否允许到S3的出站流量
- 如果网络链路正常,会直接抛出
内容的提问来源于stack exchange,提问作者michaelschufi
相关产品推荐
相关产品推荐

