I have a very basic proxy class (a friend who helped me coding it insists it's a decorator class instead) for python-mpd2.
The class looks like this
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()
This works well so far, as long as there is an mpd host available to connect to. If there is no mpd server, I get
ConnectionRefusedError: [Errno 111] Connection refused
I'm looking for good patterns to deal with this Exception
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?
The question you should ask yourself is "who is *able* to deal with that exception?"
Obviously, the proxy can't to anything sensible to "fix" ConnectionRefusedError
. So it has to be handled at upper levels.
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?
Bad idea. The normal way of informing "upper levels" than an exception has occurred is to raise
an exception. Or to let a raised exception propagate up.
Concretely:
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()