【问题标题】:AWS Lambda not showing cause Exception stacktrace in Python 3.8AWS Lambda 未在 Python 3.8 中显示原因异常堆栈跟踪
【发布时间】:2020-06-02 14:16:33
【问题描述】:

我使用运行时 Python 3.8 将以下代码部署到 AWS Lambda。

try:
    raise Exception('my exception')
except Exception as e:
    raise ValueError('my exception 2') from e

在 CloudWatch 中,我希望看到这样的异常链:

Traceback (most recent call last):
  File "/var/task/handler.py", line 2, in <module>
    raise Exception('my exception')
Exception: my exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/var/task/handler.py", line 4, in <module>
    raise ValueError('my exception 2') from e
ValueError: my exception 2

相反,我只看到 CloudWatch 中报告的第一个异常,如下所示:

[ERROR] ValueError: my exception 2
Traceback (most recent call last):
  File "/var/task/handler.py", line 21, in pevm_import_budget_file
    raise ValueError('my exception 2') from e

为什么from 语句中的direct cause 异常没有显示在日志中?

【问题讨论】:

    标签: python-3.x amazon-web-services aws-lambda


    【解决方案1】:

    您提到的行为是预期的,我也看到了同样的情况。似乎 Lambda 目前不支持链式异常。但是,为了解决这个问题,您可以添加自己的记录器来捕获异常。

    例如使用traceback检索异常堆栈:

    import traceback
    
    def lambda_handler(event, context):
        try:
            try:
                raise Exception('my exception')
            except Exception as e1:
                raise ValueError('my exception 2')
        except Exception as e2:
            traceback.print_exception(type(e2), value=e2, tb=e2.__traceback__)
    
        return {}
    

    CloudWatch 日志如下所示:

    Traceback (most recent call last):
      File "/var/task/lambda_function.py", line 6, in lambda_handler
        raise Exception('my exception')
    Exception: my exception
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/var/task/lambda_function.py", line 8, in lambda_handler
        raise ValueError('my exception 2')
    ValueError: my exception 2
    

    【讨论】:

    • 谢谢!这类作品。问题是它实际上并没有最终引发异常,因此程序继续超越异常。它不会终止。当通过raise 手动重新引发异常时,它会终止,但随后会双重记录错误(更像是记录 1.5)。我想这是在 AWS 修复它之前我们能做的最好的事情。
    【解决方案2】:

    我更喜欢的另一个解决方案是将堆栈跟踪打印到 stderr 并引发一般错误以便程序终止。示例:

    import logging, traceback, sys
    
    class ProgramError(Exception):
        def __init__(self, msg='There should be more of exception traceback above.', **kwargs):
            super(ProgramError, self).__init__(msg, **kwargs)
    
    
    def log_exception():
        exc_type, exc_value, exc_traceback = sys.exc_info()
        logging.error(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
    
    
    try:
        raise Exception('my exception')
    except Exception as e:
        log_exception()
        raise ProgramError()
    

    这会产生如下所示的 CloudWatch 输出:

    2020-06-02T06:08:57.340000+00:00 2020/06/02/[$LATEST]df0f5bb977b443f9889a809f0d1affa4 START RequestId: e609f118-75d9-4cc7-81fe-44036d492814 Version: $LATEST
    2020-06-02T06:08:57.341000+00:00 2020/06/02/[$LATEST]df0f5bb977b443f9889a809f0d1affa4 [ERROR]   2020-06-02T06:08:57.341Z    e609f118-75d9-4cc7-81fe-44036d492814    Traceback (most recent call last):
      File "/var/task/handler.py", line 35, in testfile
        raise Exception('my exception')
    Exception: my exception
    2020-06-02T06:08:57.342000+00:00 2020/06/02/[$LATEST]df0f5bb977b443f9889a809f0d1affa4 [ERROR] ProgramError: There should be more of exception traceback above.
    Traceback (most recent call last):
      File "/var/task/handler.py", line 38, in testfile
        raise ProgramError()
    2020-06-02T06:08:57.343000+00:00 2020/06/02/[$LATEST]df0f5bb977b443f9889a809f0d1affa4 END RequestId: e609f118-75d9-4cc7-81fe-44036d492814
    2020-06-02T06:08:57.343000+00:00 2020/06/02/[$LATEST]df0f5bb977b443f9889a809f0d1affa4 REPORT RequestId: e609f118-75d9-4cc7-81fe-44036d492814    Duration: 2.71 ms   Billed Duration: 100 ms Memory Size: 256 MB Max Memory Used: 95 MB  Init Duration: 1297.82 ms
    

    如果存在导致Exception 的一系列异常,它们将被列出并用The above exception was the direct cause of the following exception: 分隔。

    感谢@Paradigm 提供的灵感!希望 AWS 尽快修复对 from 的支持,这样我们就不必做这样的变通方法了。

    【讨论】:

      猜你喜欢
      • 2017-08-09
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多