我有嵌套的 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'
]
是否有更好的方法来实现这一目标,而无需迭代字符串和模式匹配?
注意: 如果除了异常消息字符串之外我还能获取异常的类型,那就完美了,例如:
[
{"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
]
你可以尝试:
import traceback
import requests
def get_info(exc):
r = []
if exc.__context__:
r += get_info(exc.__context__)
tbe = traceback.TracebackException.from_exception(exc)
r.append({"type": tbe.exc_type.__name__, "message": str(exc)})
return r
try:
r = requests.get("https://thisdoesntexist.test")
except Exception as e:
print(get_info(e))
打印:
[
{"type": "gaierror", "message": "[Errno -2] Name or service not known"},
{
"type": "NameResolutionError",
"message": "<urllib3.connection.HTTPSConnection object at 0x7fcc18e014d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)",
},
{
"type": "MaxRetryError",
"message": "HTTPSConnectionPool(host='thisdoesntexist.test', port=443): Max retries exceeded with url: / (Caused by NameResolutionError(\"<urllib3.connection.HTTPSConnection object at 0x7fcc18e014d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)\"))",
},
{
"type": "ConnectionError",
"message": "HTTPSConnectionPool(host='thisdoesntexist.test', port=443): Max retries exceeded with url: / (Caused by NameResolutionError(\"<urllib3.connection.HTTPSConnection object at 0x7fcc18e014d0>: Failed to resolve 'thisdoesntexist.test' ([Errno -2] Name or service not known)\"))",
},
]