无法在异步调用的函数中放入 Python 调试器?
Can't drop into Python debugger in a function called asynchronously?
为了调试 中描述的 Airbrake 问题,我尝试在将请求发送到 Airbrake 之前检查请求,方法是使用 import ipdb; ipdb.set_trace()
放入 iPython 调试器。
为了检查请求,我在 Notifier
的 send_notic_sync()
方法中设置了跟踪(参见 https://github.com/airbrake/pybrake/blob/master/pybrake/notifier.py):
def send_notice_sync(self, notice):
"""Sends notice to Airbrake.
It returns notice with 2 possible new keys:
- {'id' => str} - notice id on success.
- {'error' => str|Exception} - error on failure.
"""
for fn in self._filters:
r = fn(notice)
if r is None:
notice['error'] = 'notice is filtered out'
return notice
notice = r
if time.time() < self._rate_limit_reset:
notice['error'] = _ERR_IP_RATE_LIMITED
return notice
data = jsonify_notice(notice)
req = urllib.request.Request(self._airbrake_url,
data=data,
headers=self._airbrake_headers)
try:
import ipdb; ipdb.set_trace()
resp = urllib.request.urlopen(req, timeout=5)
except urllib.error.HTTPError as err:
resp = err
except Exception as err: # pylint: disable=broad-except
notice['error'] = err
logger.error(notice['error'])
return notice
此方法已提交给 pybrake
源代码中的 ThreadPoolExecutor
。问题是,当我尝试 import
调用此函数的脚本时,我无法进入调试器。这是我尝试时看到的结果:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import lucy_web.tests.test_airbrake
In [2]: ipdb>
2018-05-31 11:52:14,155 - pybrake - ERROR -
> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/pybrake/notifier.py(119)send_notice_sync()
118 import ipdb; ipdb.set_trace()
--> 119 resp = urllib.request.urlopen(req, timeout=5)
120 except urllib.error.HTTPError as err:
ipdb> ^[ipdb>
In [2]: 2018-05-31 11:52:14,159 - pybrake - ERROR -
^[[37;1R> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/pybrake/notifier.py(119)send_notice_sync()
118 import ipdb; ipdb.set_trace()
--> 119 resp = urllib.request.urlopen(req, timeout=5)
120 except urllib.error.HTTPError as err:
^[[37;1R
^[[37;1RIn [2]: dir()
In [2]: dir()
Out[2]:
['In',
'Out',
'_',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dh',
'_i',
'_i1',
'_i2',
'_ih',
'_ii',
'_iii',
'_oh',
'exit',
'get_ipython',
'lucy_web',
'quit']
所以,虽然有 'flashes' 的调试器输出,但最终我只是在我原来的 ipdb
会话的范围内。我怎样才能做到这一点,以便我可以在 send_notice_sync()
方法中设置跟踪?
我最终通过在 Notifier
的 __init__()
方法中进入调试器解决了这个问题,该方法之所以有效是因为它不是异步调用的。在这里我能够确定 project_id
被作为 None
传递,因为我没有正确设置我的 Django AIRBRAKE
设置。
为了调试 import ipdb; ipdb.set_trace()
放入 iPython 调试器。
为了检查请求,我在 Notifier
的 send_notic_sync()
方法中设置了跟踪(参见 https://github.com/airbrake/pybrake/blob/master/pybrake/notifier.py):
def send_notice_sync(self, notice):
"""Sends notice to Airbrake.
It returns notice with 2 possible new keys:
- {'id' => str} - notice id on success.
- {'error' => str|Exception} - error on failure.
"""
for fn in self._filters:
r = fn(notice)
if r is None:
notice['error'] = 'notice is filtered out'
return notice
notice = r
if time.time() < self._rate_limit_reset:
notice['error'] = _ERR_IP_RATE_LIMITED
return notice
data = jsonify_notice(notice)
req = urllib.request.Request(self._airbrake_url,
data=data,
headers=self._airbrake_headers)
try:
import ipdb; ipdb.set_trace()
resp = urllib.request.urlopen(req, timeout=5)
except urllib.error.HTTPError as err:
resp = err
except Exception as err: # pylint: disable=broad-except
notice['error'] = err
logger.error(notice['error'])
return notice
此方法已提交给 pybrake
源代码中的 ThreadPoolExecutor
。问题是,当我尝试 import
调用此函数的脚本时,我无法进入调试器。这是我尝试时看到的结果:
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py shell
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import lucy_web.tests.test_airbrake
In [2]: ipdb>
2018-05-31 11:52:14,155 - pybrake - ERROR -
> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/pybrake/notifier.py(119)send_notice_sync()
118 import ipdb; ipdb.set_trace()
--> 119 resp = urllib.request.urlopen(req, timeout=5)
120 except urllib.error.HTTPError as err:
ipdb> ^[ipdb>
In [2]: 2018-05-31 11:52:14,159 - pybrake - ERROR -
^[[37;1R> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/pybrake/notifier.py(119)send_notice_sync()
118 import ipdb; ipdb.set_trace()
--> 119 resp = urllib.request.urlopen(req, timeout=5)
120 except urllib.error.HTTPError as err:
^[[37;1R
^[[37;1RIn [2]: dir()
In [2]: dir()
Out[2]:
['In',
'Out',
'_',
'__',
'___',
'__builtin__',
'__builtins__',
'__doc__',
'__loader__',
'__name__',
'__package__',
'__spec__',
'_dh',
'_i',
'_i1',
'_i2',
'_ih',
'_ii',
'_iii',
'_oh',
'exit',
'get_ipython',
'lucy_web',
'quit']
所以,虽然有 'flashes' 的调试器输出,但最终我只是在我原来的 ipdb
会话的范围内。我怎样才能做到这一点,以便我可以在 send_notice_sync()
方法中设置跟踪?
我最终通过在 Notifier
的 __init__()
方法中进入调试器解决了这个问题,该方法之所以有效是因为它不是异步调用的。在这里我能够确定 project_id
被作为 None
传递,因为我没有正确设置我的 Django AIRBRAKE
设置。