We’ve developed a decorator intended to be placed on top of the “soapmethod” decorator that allows you to catch any exception raised by the web method.

Usage:

@catchWsExceptions
@soapmethod(String, _returns=Array(String))
def srv_whatever(self, someParam):
        # just business logic, no exception handling required.

Decorator code:

import inspect
import traceback

def catchWsExceptions(func):
    def wrapped(*args, **kwargs):
        if func.__module__ <> "soaplib.service":
                raise ApplicationException("catchWsExceptions decorator can only be used before soapmethod decorator")
        try:
            result = func(*args, **kwargs)
            return result
        except Exception,  e:
            tb= sys.exc_info()[2]
            tpl = traceback.extract_tb(tb)
            failedCall = str(tpl[-1][0])
            if re.search("soaplib", failedCall):
                Logger.getInstance().logException(e)
                raise # this is not an exception within the function but before calling the actual function
            if type(e) == type(TypeError):
                raise # API mistmach exception should not be filtered
            msg = ""
            if hasattr(e, "message"):
                msg = e.message
            Logger.getInstance().logException(e)
            return ['2', msg + str(e.args)]
    wrapped.__doc__ = func.__doc__
    wrapped.func_name = func.func_name
    wrapped._is_soap_method = True
    return wrapped

Logger and ApplicationException belong in our code base but you can just replace them. You may also raise the caught exception rather than return an array with an error code. It is a design decision.