如何处理在另一个模块中捕获的异常



是否有办法防止模块urllib3捕获KeyboardInterrupt?当KeyboardInterrupt发生时,我需要执行一些进程,但问题是urllib3模块似乎捕获异常而不传递它。

我写了一个示例脚本来演示我的问题。

connector.py

import requests
from time import sleep
class Connector:
def __init__(self):
pass
def connect(self):
try:
URL="https://www.gelbeseiten.de"
print("Connecting")
sleep(1)
print("Now")
requests.get(URL)
requests.get(URL)
requests.get(URL)
requests.get(URL)
except Exception as e:
print("Exception in connect")
raise Exception()

main.py

import connector
def main():
try:
conn=connector.Connector()
conn.connect()
except Exception as e:
print("Exception in main")
if __name__ == '__main__':
main()

如果脚本正在执行GET请求,我执行一个KeyboardInterrupt (Ctrl + C),我所期望的是第一个"Exception in connect"然后"Exception in main"但是我得到了以下输出

Traceback (most recent call last):
File "/tmp/test/main.py", line 11, in <module>
main()
File "/tmp/test/main.py", line 6, in main
conn.connect()
File "/tmp/test/connector.py", line 16, in connect
requests.get(URL)
File "/usr/lib/python3/dist-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 428, in __exit__
self.close()
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 747, in close
v.close()
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 325, in close
self.poolmanager.clear()
File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 222, in clear
self.pools.clear()
File "/usr/lib/python3/dist-packages/urllib3/_collections.py", line 100, in clear
self.dispose_func(value)
File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 173, in <lambda>
self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close())
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 491, in close
if conn:
KeyboardInterrupt

这表明模块urllib3得到了中断信号,并没有将其传递给我的异常处理程序。它们是一种获得我预期行为的方法吗?

KeyboardInterrupt不会被捕获。

KeyboardInterrupt

异常当用户点击中断键(通常为Control-C或Delete)时引发。在执行过程中,定期检查中断。该异常继承自BaseException,以便不会被捕获exception的代码意外捕获,从而阻止解释器退出。

看到https://docs.python.org/3/library/exceptions.html KeyboardInterrupt

这里的问题是KeyboardInterrupt不是Exception的子类。如果您特别想捕获KeyboardInterrupt,则必须使用except KeyboardInterrupt as e:

同时,最好使用raise e而不是引发一个新的Exception

我认为你需要改变你的raise脚本,因为KeyboardInterrupt似乎不像继承自Exception。相反,它来自BaseException。请为您的connector.py尝试以下代码。

import requests
from time import sleep
class Connector:
def __init__(self):
pass
def connect(self):
try:
URL="https://www.gelbeseiten.de"
print("Connecting")
sleep(1)
print("Now")
requests.get(URL)
requests.get(URL)
requests.get(URL)
requests.get(URL)
except Exception as e:
print("Exception in connect")
raise Exception()
except KeyboardInterrupt as e:
print("Keyboard interrupt")
raise Exception

最新更新