2014-08-30 69 views
0

對於python-mpd2,我有一個非常基本的代理類(幫助我編碼的朋友堅持認爲它是裝飾類)。如何處理代理類中的不可用主機(ConnectionRefusedError)

類看起來像這樣

import mpd 

class MPDProxy: 
    def __init__(self, host="localhost", port=6600, timeout=10): 
     self.client = mpd.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) 

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

mpd_proxy = MPDProxy() 

這至今,只要有可用的MPD主機連接到效果很好。如果沒有MPD服務器,我得到

ConnectionRefusedError: [Errno 111] Connection refused

我正在尋找好的模式來處理這個異常

  • 你能想到的一個優雅的方式來防止程序崩潰,當有沒有可用的主機?
  • 我應該在代理內還是外部捕獲異常,每當代理被調用?
  • 是一個字符串「主機不可用」(或類似)作爲返回值是一個好主意,或者可以通過更好的方式通知調用代理的方法/函數嗎?

回答

1

Can you think of an elegant way to prevent the program to crash, when there is no host available?

try ... except;)


Should I catch the exception within the proxy or outside, whenever the proxy is called?

你應該問自己的問題是「誰是*能*處理該異常?」


很明顯,代理服務器不能爲任何明智的「修復」ConnectionRefusedError。所以它必須在上層處理。


Is a string "Host not available" (or similar) as a return value a good idea or can a method/function calling the proxy be informed in a better way?

壞主意。通知「上層」的例外情況的正常方式是raise例外。或者讓一個提出的異常傳播起來。


具體:

class MPDProxy: 
    def _call_with_reconnect(self, func): 
     def wrapper(*args, **kwargs): 
      try: 
       return func(*args, **kwargs) 
      except mpd.ConnectionError: 
       self.connect(self.host, self.port) 
       # ^^^^^^ This lime might raise `ConnectionRefusedError` 
       # as there is no `except` block around, this exception 
       # is automatically propagated  

       return func(*args, **kwargs) 
     return wrapper 

try: 
    mpd_proxy = MPDProxy() 
    r = mdp_proxy._call_with_reconnect(whatever) 
except ConnectionRefusedError: 
    do_somesible_sensible() 
+0

很好的答案!事實上,對於被拒絕的連接,上層也無能爲力。在具體的情況下(一個Django項目),我只想要一個信息框「MPD服務器不可用」或類似顯示) – speendo 2014-08-30 08:31:35

+1

@speendo Display + log maybe? (見日誌模塊) – 2014-08-30 08:36:33

+0

@ sylvian-leroux是的。以爲我可以直接在MPDProxy中以DRY的方式執行此操作......順便說一下,我認爲'除了ConnectionRefusedError:...'應該放在'self.connect(self.host,self。端口)''但我不完全確定 – speendo 2014-08-30 08:40:38