如何正确捕获模块引发的异常?

时间:2014-02-14 20:02:13

标签: python python-3.x

在python项目中,我使用连接到(mpd。)服务器的模块python-mpd2。服务器在一分钟后关闭连接。然后,模块提供的大多数方法都会生成mpd.ConnectionError

我尝试构建一个尝试执行该方法的包装类,但在以前断开连接的情况下重新连接到服务器。

我拥有的是:

from mpd import MPDClient, MPDError

class MPDProxy:
    def __init__(self, host="localhost", port=6600, timeout=10):
        self.client = MPDClient()
        self.host = host
        self.port = port

        self.client.timeout = timeout
        self.connect(host, port)

    def __getattr__(self, name):
        return self._call_with_reconnect(getattr(self.client, name))

    def connect(self, host, port):
        self.client.connect(host, port)
        self.client.consume(1) # when we call self.client.next() the previous stream is deleted from the playlist
        if len(self.client.playlist()) > 1:
            cur =  (self.client.playlist()[0][6:])
            self.client.clear()
            self.add(cur)

    def _call_with_reconnect(self, func):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except ConnectionError:
                self.connect(self.host, self.port)
                return func(*args, **kwargs)
        return wrapper

mpd_proxy = MPDProxy()

但是,ConnectionError不会被捕获。

>>> from MPDProxy import mpd_proxy
>>> mpd_proxy.play()
>>> mpd_proxy.stop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./MPDProxy.py", line 26, in wrapper
    func(*args, **kwargs)
  File "/usr/local/lib/python3.3/dist-packages/mpd.py", line 588, in decorator
    return wrapper(self, name, args, bound_decorator(self, returnValue))
  File "/usr/local/lib/python3.3/dist-packages/mpd.py", line 229, in _execute
    return retval()
  File "/usr/local/lib/python3.3/dist-packages/mpd.py", line 583, in decorator
    return function(self, *args, **kwargs)
  File "/usr/local/lib/python3.3/dist-packages/mpd.py", line 352, in _fetch_nothing
    line = self._read_line()
  File "/usr/local/lib/python3.3/dist-packages/mpd.py", line 260, in _read_line
    raise ConnectionError("Connection lost while reading line")
mpd.ConnectionError: Connection lost while reading line

我如何才能正确捕获ConnectionError?

3 个答案:

答案 0 :(得分:3)

您需要以下内容:

 def connect(self):
    try:
        self.client.connect(self._host, self._port)
    # Catch socket errors
    except IOError as err:
        errno, strerror = err
        raise PollerError("Could not connect to '%s': %s" %
                          (self._host, strerror))

    # Catch all other possible errors
    # ConnectionError and ProtocolError are always fatal.  Others may not
    # be, but we don't know how to handle them here, so treat them as if
    # they are instead of ignoring them.
    except MPDError as e:
        raise PollerError("Could not connect to '%s': %s" %
                          (self._host, e))

有关详细信息,请查看Documentation下的示例 此外,根据您的错误消息,ConnectionError捕获的正确错误是mdp.ConnectionError。 ConnectionError是由mdp。

定义的异常

答案 1 :(得分:1)

编辑:尝试在代码中导入mpd模块。

import mpd

然后更改一行:

except ConnectionError

通过

except mpd.ConnectionError

答案 2 :(得分:1)

导入异常类型,或者更确切地说,导入整个dang模块并通过其模块引用异常。 不要只抓住所有例外情况!你会抓住你不想做的事情而且你会有无声的失败。

import mpd
# alternatively, from mpd import ConnectionError

try:
    # your code here
except mpd.ConnectionError as mpdece:
    # handle that exception!

最好导入模块,因为假设您导入的两个模块有一个名为ConnectionError的模块。您可能会将另一个ConnectionError隐藏起来。

如果要导入名称较长的模块,可以执行import module_with_long_name as mwln等。