【问题标题】:Silent Failure of S3 PutObject?S3 PutObject 静默失败?
【发布时间】:2019-07-19 08:06:33
【问题描述】:

我一直在尝试使用 S3.Object.put() 方法以编程方式将 SNS 消息上传到 S3 存储桶,如下所示:

bucket_resource=boto3.resource('s3')
bucket_client = boto3.client('s3')
body = subject + message
object = bucket_resource.Object(bucket_name, folder+'/'+fn)
object.put(Body=body)

这不起作用,所以我尝试了以下方法来尝试将对象上传到特定的 S3 存储桶。

body = subject + message
folder = datetime.datetime.today().strftime('%Y-%m-%d')
fn = datetime.datetime.today().strftime('%H:%M:%S')
key = folder_name + '/' + fn
bucket_resource = s3.Bucket(bucket_name)
bucket.upload_file(body, key)

但是,这两种方法都默默地失败了。我没有收到任何拒绝访问、错误消息等,但我也没有将我的消息上传到存储桶。我不确定每次调用该函数会发生什么,如果以编程方式成功将文件上传到存储桶的人,我将不胜感激。

注意: 我有存储桶策略,我的帐户是唯一可以将对象放入存储桶的帐户。我是否需要附录来授予 Lambda 将对象放入存储桶的权限?

【问题讨论】:

  • 为了防止异常被默默吞下,必须需要如下所示的 try/except 似乎是不可想象的。未处理的异常应该会导致崩溃。 (对吗?我的意思是……对吗?)您如何确认文件不存在?如果您记录它,key 的值会恢复吗?这是一个可以尝试的技巧:将存储桶名称设置为“上传”。这恰好是 AWS 在某种阻止或保留列表中的存储桶名称,当您尝试对其进行写入或读取时,该名称总是引发异常。如果 that 没有抛出异常,那我会很惊讶。
  • 在第二个例子中,bucket.upload_file(body, key)不应该是bucket_resource.upload_file(body, key)吗?
  • @JohnRotenstein 实际上,它应该是 bucket_client.upload_file,这是我的疏忽。我有一个 try/except 来捕获文件是否已成功上传,并且我的日志告诉我,尽管没有键/值错误,但我没有将文件上传到 S3 存储桶。
  • 在这种情况下,我建议从硬编码的upload_file() 命令开始,以确认它可以正常工作(例如bucket_resource.upload_file('abc','test.txt')。如果可以,那么问题出在身体或关键。如果它不起作用,那么您需要尝试找出问题所在。
  • 我在使用bucket_resource.upload_file() 的地方看到了类似的东西......无法弄清楚问题是什么。

标签: python python-3.x amazon-web-services amazon-s3


【解决方案1】:

对我来说也没有错误,但我使用的是 .NET Core SDK。原来我的问题是功能在它能够将文件放入 S3 之前完成。在 .NET SDK 中,PutObject 调用是异步的 (PutObjectAsync),即使我在等待它完成,但由于我拥有的函数层,我没有正确执行该操作。

对于在 S3 中没有错误且没有文件的任何人,请在文件实际上传到 S3 之前检查您的函数是否未完成。

【讨论】:

    【解决方案2】:

    我没有使用过 python,但是我遇到了类似的问题,当我使用 s3.upload() 时,我的 react 应用程序崩溃了。以下答案帮助我解决了它。 https://stackoverflow.com/a/57139331/5295723

    我必须将 base64 图像缓冲区转换为二进制,并且它可以工作。

    【讨论】:

      【解决方案3】:

      请参阅here 在 python 中处理错误。

      基本上围绕 sdk 调用尝试/捕获异常,类似于:

      import boto3
      from botocore.exceptions import ClientError, ParamValidationError
      
      try:
          bucket_resource=boto3.resource('s3')
          bucket_client = boto3.client('s3')
          body = subject + message
          object = bucket_resource.Object(bucket_name, folder+'/'+fn)
          object.put(Body=body)
      except s3.exceptions.<fill in>:
          print("known error occured")
      except ClientError as e:
          print("Unexpected error: %s" % e)
      

      This is the link the original poster provided,它显示了您可以为 S3 客户端捕获的可能异常

      【讨论】:

      • 这不适用于我的帖子。我没有收到任何错误,我相信我在最初的问题中发布了它。我没有收到错误,但也没有创建对象。
      • 是的,您没有收到任何错误,因为您没有发现任何错误,这就是它们保持沉默的原因
      • 我觉得 Cloudwatch 会告诉我,如果我的 lambda 因我没有发现的错误而失败。 Cloudwatch 报告我的函数成功执行。如果 Lambda 函数有任何错误,该函数将失败。
      • 不一定。除非您正在记录错误,否则它不会记录它,因为它假设您不想看到它。如果一段代码在其中失败,您是否希望函数失败也是如此。如果您处理错误并告诉它不要,或者如果您不处理错误并且什么都不告诉它,Lambda 不会失败,它会认为它的工作已经完成。
      • 我的个人经验主要是使用 nodejs lambdas,但我假设基于该经验的所有人的行为都是相同的。尝试使用 try/catch 看看会发生什么,值得一试
      猜你喜欢
      • 2020-10-09
      • 2016-10-08
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多