2014-02-14 69 views
0

在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?

+0

我沒有看到'在你的代碼decorator'任何地方。 – BrenBarn

+0

你可以在此擴展嗎?我知道有提到裝飾器的錯誤消息,但我沒有在我的代碼中使用它。 – speendo

回答

1

編輯:嘗試在代碼中導入mpd模塊。

import mpd 

,然後更改行:

except ConnectionError 

通過

except mpd.ConnectionError 
+0

感謝您的回答。你能更精確嗎?你確定嗎?因爲如果我使用'except:'而不是'除了ConnectionError',它就可以工作。 – speendo

+0

啊,好的,試試:'mpd.ConnectionError'除外根據你的錯誤信息,這是正確的例外。 –

+0

我試過了。它不會被認可... – speendo

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)) 

欲瞭解更多信息這一看下的例子 此外,根據您的錯誤消息,要獲得ConnectionError的正確錯誤爲mdp.ConnectionError。 ConnectionError是由mdp定義的異常。

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