【发布时间】:2018-03-14 16:13:03
【问题描述】:
我在一个类内部有一个定义,它以我不喜欢的方式处理异常。
类本身在一个模块中,它本身由我导入的模块调用。
我不喜欢的错误处理如下:
class BitSharesWebsocket(Events):
#[snip]
def run_forever(self):
""" This method is used to run the websocket app continuously.
It will execute callbacks as defined and try to stay
connected with the provided APIs
"""
cnt = 0
while not self.run_event.is_set():
cnt += 1
self.url = next(self.urls)
log.debug("Trying to connect to node %s" % self.url)
try:
# websocket.enableTrace(True)
self.ws = websocket.WebSocketApp(
self.url,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close,
on_open=self.on_open
)
self.ws.run_forever()
except websocket.WebSocketException as exc:
if (self.num_retries >= 0 and cnt > self.num_retries):
raise NumRetriesReached()
sleeptime = (cnt - 1) * 2 if cnt < 10 else 10
if sleeptime:
log.warning(
"Lost connection to node during wsconnect(): %s (%d/%d) "
% (self.url, cnt, self.num_retries) +
"Retrying in %d seconds" % sleeptime
)
time.sleep(sleeptime)
我希望在这里抢占异常:
except websocket.WebSocketException as exc:
并以我自己的方式处理它,即尝试一个新地址,而不是一次又一次地尝试相同的地址。
调用时出现此异常:
from bitshares.blockchain import Blockchain
from bitshares import BitShares
try:
chain = Blockchain(bitshares_instance=BitShares(n))
except:
print ('hello world')
pass
当 n 是错误/无响应的 websocket 地址时
我从来没有收到“hello world”消息,因为模块在我之前处理了异常。
该模块托管在 github 此处:
我能做到:
from bitsharesapi import websocket as ws
但我不确定如何处理模块 ws,因为它被导入以抢占其异常处理,或者这是否是处理它的正确方法。
【问题讨论】:
-
简短的回答:没有办法以这种方式“抢占”异常处理 - 当然除了分叉整个事情并按照自己的方式重写。更长的答案:从技术上讲,可能有一种方法可以做到 - 但它会比分叉更加复杂和不可维护。请注意,如果您 fork 项目,您可以尝试以保持兼容性的方式重写它,然后将您的 fork 提交给项目的维护者。
-
我已经联系了开发人员并建议他简单地提出异常,让用户以自己的方式处理它。我一直在寻找“直到发生”的解决方案。我目前正在使用多进程来覆盖和强制超时;但这在您提到的实践中存在一些缺点。我希望“从 bitsharesapi 导入 websocket.WebSocketException”之类的
-
那你会用它做什么?异常只是一个对象,它不是控制流。您不能在不更改该代码的情况下更改部分代码的控制流,除非给定的代码提供了这样做的钩子——通过回调或使用模板方法模式和继承——但即使那样你也只能采取(部分)控制委托给这些钩子的部分。