我能做些什么" null不是一个对象(评估' p')"何时创建AWS Lambda?

时间:2017-02-02 17:04:14

标签: aws-lambda

我正在尝试创建AWS Lambda。我编写了一个带有单个依赖项的小型Python 2.7脚本(boto3)。要将脚本转换为Lambda,请执行以下步骤:

  1. 我使用python-lambda library运行lambda deploy以构建可上载的ZIP文件。出于某种原因,它在实际上传文件的步骤中失败了,但它产生了一个ZIP。
  2. 我将ZIP文件上传到AWS Lambda页面的“代码”标签。
  3. 点击“保存并测试”。
  4. 我希望这会运行我的脚本并产生一些输出 - 事实上,这已经有数十次迭代了。但是我对我的脚本进行了一些小的代码更改(更改了两行,下面是diff) - 现在,我得到了一条不友好的红色错误消息:

      

    null不是对象(评估' p')

    这是它的样子:

    enter image description here

    对我而言,这听起来更像是一个JavaScript错误,而不是一个Python错误 - 我该怎么做才能解决这个问题?

    我已经尝试过了:

    • 使用新文件创建一个新的ZIP文件并重新上传 - 没有区别。
    • 上传到S3存储桶,并从那里加载代码。我的ZIP文件是9.4MB,所以我认为直接上传应该没问题 - 无论哪种方式,都没有区别。
    • 创建一个新的Lambda函数 - 错误跟随我到新的。
    • 更改代码。比较ZIP文件的内容,如果我忽略编译的PYC文件,这是唯一的区别:

      diff -r /Users/chana/repos/terraform-lambda/bisect/2017-02-02-161207-my_lambda_function/service.py /Users/chana/repos/terraform-lambda/bisect/2017-02-02-161437-my_lambda_function/service.py
      25,26c25,26
      <     subprocess.check_call(['unzip', '/tmp/terraform_0.8.5_linux_amd64.zip'])
      <     subprocess.check_call(['terraform', '--version'])
      ---
      >     subprocess.check_call(['unzip', '/tmp/terraform_0.8.5_linux_amd64.zip', '-d', '/tmp/terraform_0.8.5'])
      >     subprocess.check_call(['/tmp/terraform_0.8.5/terraform', '--version'])
      

      如果我在此更改之前恢复到版本,我将不再收到错误消息。我已经打了几次 - 我不完全确定我的代码中的更改会如何影响错误的可能性。我可以对我的代码进行微不足道的编辑,直到Lambda再次开始喜欢它,但这不是一个特别有用或有效的调试方法。

    • 查看Web Inspector控制台 - 它很干净。如果这是一个JavaScript错误,则不会发生在客户端。

    • 搜索Google和SO,但我没有找到任何有用的内容。我不确定这是否意味着什么,或者它只是在一堆无关的JavaScript错误中迷失了。

1 个答案:

答案 0 :(得分:0)

事实证明,当您将空字节打印到stdout时,AWS Lambda会感到痛苦。

在剧本结束时,我从S3抓取Terraform计划并打印到stdout:

top

我最初没有意识到的是,如果最后一行被执行,我就会遇到错误。如果我之前在脚本中的更改导致它引发异常,则它不会触及此行并且脚本将完成(尽管有Python异常)。如果脚本的其余部分干净利落,那么Lambda就会崩溃。

Terraform计划文件是二进制文件,因此将其打印到stdout可能包含一些奇怪的字节字符串。在一些二等分之后,我能够减少到两个最小的例子。将这些内容粘贴到Python 2.7的默认Lambda中可能会触发错误。

  1. 在某些情况下,我收到内部服务器错误。以下脚本可靠地触发:

    s3 = boto3.resource('s3')
    o = s3.Object(bucket_name, '/path/to/terraform.plan')
    print(len(o.get()['Body'].read()))
    
  2. 在其他情况下,我得到 null不是对象。以下脚本可靠地触发:

    def lambda_handler(event, context):
        print('\x00')
    
  3. 我认为这不仅仅是空字节 - 如果我混入def lambda_handler(event, context): print('\x00\x00') \x01,我会得到相同的行为。

    这里的教训是,我应该小心我正在打印的内容!