Lambda中s3.touch无法执行:如何排查错误及解决?
问题描述
已创建S3存储桶及文件夹,相关值传入AWS Lambda后,打印语句能正常输出存储桶和文件夹名称,但s3.touch功能未执行,也捕获不到错误信息,怀疑是IAM权限问题。想知道如何显示错误信息,以及解决方法。
代码示例
import boto3 import uuid import s3fs # S3 bucket info s3 = s3fs.S3FileSystem(anon=False) def lambda_handler(event, context): #below line is added only to make it run from local pycharm client = boto3.client('s3') input_archive_folder = 'test' # event['inputArchiveFolder'] output_path = input_archive_folder+'_'+str(uuid.uuid4()) + "/" + "output" file_row_limit = 600 # event['fileChunkSize'] ----No. of records we want to put in file file_delimiter =',' # event['fileDelimiter'] record = event['Records'][0] print(record) bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] print(key) create_start_indicator(bucket, output_path) def create_start_indicator(bucket, folder_name): print(f'IN create_start_indicator {bucket} {folder_name}') try: response = s3.touch(bucket + "/" + folder_name + "/_started") print(response) except error as e: print("Unexpected error: %s" % e)
解决方法
第一步:修复错误捕获,显示真实错误信息
你的代码里except error as e:是语法错误——Python没有名为error的内置异常类,这导致异常根本没被捕获,自然看不到错误日志。改成以下两种方式之一即可:
方式1:捕获所有通用异常
except Exception as e: print(f"Unexpected error: {str(e)}") # 也可以用Lambda日志工具更规范输出 import logging logging.error(f"Error creating _started file: {str(e)}")
方式2:捕获s3fs特定异常(更精准)
s3fs有专属异常类,针对性捕获能更清晰区分错误类型:
from s3fs.errors import S3FSError # ... 其他代码 ... except S3FSError as e: print(f"S3FS Error: {str(e)}") except Exception as e: print(f"Other Error: {str(e)}")
修改后重新部署Lambda,就能在CloudWatch日志里看到具体错误——不管是权限问题、路径格式问题还是其他问题,都会被打印出来。
第二步:解决IAM权限问题
如果错误信息显示AccessDenied,说明Lambda执行角色缺少S3写入权限。需要给角色添加以下IAM权限策略:
最小权限策略(推荐)
只允许在目标桶的指定路径下创建文件,避免过度授权:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }
把YOUR_BUCKET_NAME替换成你的存储桶名称。如果只需要特定路径,可以把*改成更具体的前缀,比如test_*/output/_started。
操作步骤
- 打开IAM控制台,找到Lambda对应的执行角色
- 点击「添加权限」→「创建内联策略」
- 选择S3服务,动作选
PutObject,资源指定你的桶路径 - 保存策略,重新测试Lambda
另外注意:s3.touch本质是创建空对象,你的路径格式bucket/folder/_started是正确的,不需要额外前缀。
内容的提问来源于stack exchange,提问作者pbh
相关产品推荐
相关产品推荐

