想象一下以下代码:
def query(sql, data):
with conn as cursor:
try:
cursor.execute(sql, data)
rows = cursor.fetchall()
conn.commit()
except Exception as e:
print(cursor._last_executed)
print(e)调用它时,err.InterfaceError("(0, '')")将从最后一行print(e)中上升。
如果它是从print(cursor._last_executed)中崛起的,我甚至可以理解它,因为cursor可能是不可用的。但事实并非如此。
为什么,当我的异常应该处理所有事情的时候?
请不要去讨论简单的例外是好的还是坏的,这是另一个话题。问题是,在这种情况下,为什么会出现例外。
编辑:异常在很重的DB负载下很少出现。你将无法复制它。
Edit2:我成功地将跟踪复制为哨兵报告中的文本:
InterfaceError: (0, '')
File "run_signal_generator.py", line 39, in <module>
main()
File "run_signal_generator.py", line 35, in main
ds.run_trades_stream()
File "/home/deribit/rubber-band/data_stream/data_streamer.py", line 223, in run_trades_stream
self.process_data(data)
File "/home/deribit/rubber-band/data_stream/data_streamer.py", line 97, in process_data
self.start_new_candle(timeframe)
File "/home/deribit/rubber-band/data_stream/data_streamer.py", line 117, in start_new_candle
self.notify()
File "/home/deribit/rubber-band/data_stream/observer.py", line 13, in notify
observer.update()
File "/home/deribit/rubber-band/data_stream/observer.py", line 26, in update
self.process_data()
File "/home/deribit/rubber-band/data_stream/signal_generator.py", line 131, in process_data
return self.process_potential_new_trade()
File "/home/deribit/rubber-band/data_stream/signal_generator.py", line 160, in process_potential_new_trade
return self.process_enter_signal()
File "/home/deribit/rubber-band/data_stream/signal_generator.py", line 407, in process_enter_signal
trade_id = self.store_enter_signal_db(data)
File "/home/deribit/rubber-band/data_stream/signal_generator.py", line 522, in store_enter_signal_db
return query(sql, db_data)["id"]
File "/home/deribit/rubber-band/helpers/mysql.py", line 19, in query
print(e)
File "pymysql/connections.py", line 881, in __exit__
self.commit()
File "pymysql/connections.py", line 798, in commit
self._execute_command(COMMAND.COM_QUERY, "COMMIT")
File "pymysql/connections.py", line 1122, in _execute_command
raise err.InterfaceError("(0, '')")实际上,它声称例外是从这条线上升的。
发布于 2020-01-22 10:52:00
算出来了。
这就是正在发生的事情:
1)主query引发一个错误。
( 2)处理。
3)由于query位于上下文管理器中,上下文管理器将退出它的对象,例如连接实例。
4)由于MySQL服务器的消失,连接类的__exit__方法无法正确执行。
5)由于不能正确执行,它在上下文管理器的范围内,在query内部的裸处理异常范围之外,引发一个错误query。
如果您使用以下代码进行实验,可以获得相同的结果:
class ContextManagerException(Exception):
pass
class TryBlockException(Exception):
pass
class A(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, tb):
raise ContextManagerException
with A() as a:
try:
raise TryBlockException
pass
except Exception as e:
print(e)如您所见,上升的异常确实是从上下文管理器上升的,实际上它是从print(e)行上升的,因为它是从上下文管理器执行的最后一行。
发布于 2020-01-22 09:20:00
看起来类似于this old question:mysql连接和游标并不是线程安全的,所以如果您在多个线程之间共享连接(而不是每个线程有一个连接),那么它们的状态基本上随时都会中断。
可能由于某种原因,MySQL上的__str__连接错误使服务器尝试获取更多信息,如果其他线程已经更改了连接状态,这些信息就会中断。cursor._last_executed可能没有这个问题,因为在执行请求或响应返回时只在本地保存信息。
正如其他评论者所指出的,如果您得到一个异常,请提供完整的跟踪和错误消息,而不是信息的一小部分。如果您需要匿名,部分追溯,但ESP或假设是必要的越少,越好。
https://stackoverflow.com/questions/59856128
复制相似问题