The problem was that I needed different error handling via exceptions for different methods. Some of the methods needed one type of error handling and some needed another. What I wanted to do was to centralize the error handling. The alternative (at least the one that came to mind) was to duplicate the error handling in each method. Yuck.
Python has a nice feature called decorators which, to my understanding, allows one to wrap a method with some other code. I wrapped each applicable method that needed this error handling with an error handling decorator.
Enough narrative, let's look at the code!
from socket import error as SocketError
from pylib.util import config
from ZSI.client import Binding
from ZSI import ZSIException
class WebServiceError(Exception): pass
class InvalidURLError(WebServiceError): pass
class DatabaseNotReadyError(WebServiceError): pass
'''A decorator to wrap web service calls with consistent error handling.'''
def _execute(*args, **kwargs):
result = fn(*args, **kwargs)
except (SocketError, TypeError), e:
except ZSIException, e:
# Handle SOAP Faults.
# Check specifically if the SOAP message starts with an ODBC error string.
# If it does then the FileMaker server is unavailable.
if re.search(_WebService.odbc_error_pattern, str(e)):
except Exception, e:
raise WebServiceError("Unhandled exception: %s" % e)
Later in the program I invoke the decorator be preceding the method definition. The method that follows is effectively wrapped. For example,
result = self.binding.getSettings()