我有嵌套的Python异常.我不想从回溯中将所有这些提取到一个列表中,同时丢弃其他所有内容,即文件,代码行等.

下面的代码将回溯中的所有内容提取为字符串列表

import traceback
import requests


try:
    r = requests.get('https://thisdoesntexist.test')
except Exception as e:
    exc = traceback.format_exception(e)

print(exc)

输出:

[
    'Traceback (most recent call last):\n',
    '  File "c:\\Python312\\Lib\\site-packages\\urllib3\\connection.py", line 203, in _new_conn\n    sock = connection.create_connection(\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
    '  File "c:\\Python312\\Lib\\site-packages\\urllib3\\util\\connection.py", line 60, in create_connection\n    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
    '  File "c:\\Python312\\Lib\\socket.py", line 963, in getaddrinfo\n    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n',
    'socket.gaierror: [Errno 11001] getaddrinfo failed\n',
    '\nThe above exception was the direct cause of the following exception:\n\n',
    'Traceback (most recent call last):\n',
  
    # Output truncated

    'requests.exceptions.ConnectionError: HTTPSConnectionPool(host=\'thisdoesntexist.test\', port=443): Max retries exceeded with url: / (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x0000025E6C236600>: Failed to resolve \'thisdoesntexist.test\' ([Errno 11001] getaddrinfo failed)"))\n'
]

但我只需要这个:

[
    'socket.gaierror: [Errno 11001] getaddrinfo failed',
    'urllib3.exceptions.NameResolutionError: <urllib3.connection.HTTPSConnection object at 0x0000025E6C236600>: Failed to resolve 'thisdoesntexist.test' ([Errno 11001] getaddrinfo failed)',
    'urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=\'thisdoesntexist.test\', port=443): Max retries exceeded with url: / (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x0000025E6C236600>: Failed to resolve \'thisdoesntexist.test\' ([Errno 11001] getaddrinfo failed)"))',
    'requests.exceptions.ConnectionError: HTTPSConnectionPool(host=\'thisdoesntexist.test\', port=443): Max retries exceeded with url: / (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x0000025E6C236600>: Failed to resolve \'thisdoesntexist.test\' ([Errno 11001] getaddrinfo failed)"))\n'
]

有没有更好的方法来实现这一点,而不需要迭代字符串和模式匹配?

NB:如果除了异常消息字符串之外,我还能获得一种类型的异常,那就太好了,例如:

[
    {"type": "socket.gaierror", "message": 'socket.gaierror: [Errno 11001] getaddrinfo failed'},
    {"type": "urllib3.exceptions.NameResolutionError", "message": 'urllib3.exceptions.NameResolutionError: <urllib3.connection.HTTPSConnection object at 0x0000025E6C236600>: Failed to resolve \'thisdoesntexist.test\' ([Errno 11001] getaddrinfo failed)'},

    # etc

]

推荐答案

您可以try :

import traceback

import requests


def get_info(exc):
    r = []

    if exc.__context__:
        r += get_info(exc.__context__)

    tbe = traceback.TracebackException.from_exception(exc)

    t = tbe.exc_type.__module__ + "." + tbe.exc_type.__qualname__

    r.append({"type": t, "message": str(exc)})
    return r


try:
    r = requests.get("https://thisdoesntexist.test")
except Exception as e:
    print(get_info(e))

打印:

[
    {"type": "socket.gaierror", "message": "[Errno -2] Name or service not known"},
    {
        "type": "urllib3.exceptions.NameResolutionError",
        "message": "<urllib3.connection.HTTPSConnection object at 0x7f6cc693d9d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)",
    },
    {
        "type": "urllib3.exceptions.MaxRetryError",
        "message": "HTTPSConnectionPool(host='thisdoesntexist.test', port=443): Max retries exceeded with url: / (Caused by NameResolutionError(\"<urllib3.connection.HTTPSConnection object at 0x7f6cc693d9d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)\"))",
    },
    {
        "type": "requests.exceptions.ConnectionError",
        "message": "HTTPSConnectionPool(host='thisdoesntexist.test', port=443): Max retries exceeded with url: / (Caused by NameResolutionError(\"<urllib3.connection.HTTPSConnection object at 0x7f6cc693d9d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)\"))",
    },
]

Python相关问答推荐

多处理代码在while循环中不工作

Pandas 在最近的日期合并,考虑到破产

点到面的Y距离

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

如何在polars(pythonapi)中解构嵌套 struct ?

NumPy中条件嵌套for循环的向量化

如何使用Pandas DataFrame按日期和项目汇总计数作为列标题

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

合并帧,但不按合并键排序

旋转多边形而不改变内部空间关系

* 动态地 * 修饰Python中的递归函数

基于行条件计算(pandas)

下三角形掩码与seaborn clustermap bug

OpenCV轮廓.很难找到给定图像的所需轮廓

如何求相邻对序列中元素 Select 的最小代价

查看pandas字符列是否在字符串列中

从嵌套极轴列的列表中删除元素

当HTTP 201响应包含 Big Data 的POST请求时,应该是什么?  

Polars表达式无法访问中间列创建表达式

递归链表反转与打印语句挂起