2014-08-30 101 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