Hello everybody:
    I'm making some kind of development related to invoke externally from a Java Applet some ZOPE product methods via XML-RPC.
    I use ZOPE as the XMLRPC server, as it can 'listen' for XMLRPC requests, find the method requested using URL and traversal, invoke the method and receive the return value of it and then encapsulate the result in a XMLRPC response.
    Anyways, I want to report some exceptions from my ZOPE product python methods through XML-RPC to the applet. As my methods don't work directly with XMLRPC, all is embedded inside ZOPE, all the XMLRPC works are transparent for my python methods, so I didn't realize how I could do it.
    After looking for the ZOPE code responsible of the XMLRPC request process and XMLRPC response generation I found that some of the work was being done in ZPublisher xmlrpc.py code (Response stuff).
    Then when I started to read the comments of the code I found this in the Response class of the code:
            """ It's probably possible to improve the 'exception' method quite a bit. The current implementation, however, should suffice for now. """
    But as you will see is not enough, at least for my needs.
    I want to define my own exceptions in my product, this exceptions could be defined as follows:
        class MyOwnException:
            __init__(self, faultCode, faultString):
                self.faultCode = faultCode
                self.faultString = faultString
        Obviously I want to map XMLRPC-like fault format.
        Then, I could raise this exception from my method, and I will want that the class responsible of making the XMLRPC Response for my XMLRPC client will use it for composing the XML for XMLRPC using my fault code and fault string.
        But I found that xmlrpc.py doesn't take into account that (i'm talking of ZOPE 2.6.0) so i had to make some changes in the code of ZPublisher/xmlrpc.py:
            def exception(self, fatal=0, info=None,
                  absuri_match=None, tag_search=None):
                  # Fetch our exception info. t is type, v is value and tb is the
                  # traceback object.
                  if type(info) is type(()) and len(info)==3: t,v,tb = info
                      t,v,tb = sys.exc_info()
                  # Don't mask 404 respnses, as some XML-RPC libraries rely on the HTTP
                  # mechanisms for detecting when authentication is required. Fixes Zope
                  # Collector issue 525.
                  if t == 'Unauthorized' or (isinstance(t, types.ClassType)
                                   and issubclass(t, Unauthorized)):
                    return self._real.exception(fatal=fatal, info=info)
                  # Create an appropriate Fault object. Containing error information
                    # Strip HTML tags from the error value
                    v = str(v)
                    remove = [r"<[^<>]*>", r"&[A-Za-z]+;"]
                    for pat in remove:
                        v = re.sub(pat, " ", v)
                        from Globals import DevelopmentMode
                        if DevelopmentMode:
                            from traceback import format_exception
                            value = '\n' + ''.join(format_exception(t, v, tb))
                            value = '%s - %s' % (t, v)
                        ######  my own extension for catching user exceptions START #####
                          faultCode = getattr(sys.exc_info()[1],'faultCode')
                          faultString = getattr(sys.exc_info()[1],'faultString')
                          print "no according exception type"
                        ######  my own extension for catching user exceptions FINISH #####
                        if isinstance(v, Fault):
                        ###### my own extension for catching user exceptions START #####
                        elif (faultCode and faultString) :
                            f = xmlrpclib.Fault(faultCode,faultString)
                        ###### my own extension for catching user exceptions FINISH ######
                        elif isinstance(v, Exception):
                            f=Fault(-1, 'Unexpected Zope exception: %s' % value)
                            f=Fault(-2, 'Unexpected Zope error value: %s' % value)
                      f=Fault(-3, "Unknown Zope fault type")
                  # Do the damage.
                  return tb
        By that way, I could send my own fault code and fault descriptions via XML-RPC.
        But as you can see, I have to extend ZOPE code, and I don't want to do it, I have to work with standard releases of ZOPE.
        Do you think that something like that would be improved in an early future for next ZOPE releases?
        Any opinion will be really appreciated.
        Thanks for advance.
Aitor Illarramendi Amilibia
Ingeniero de software
Mando y Control
Carretera de Loeches, 9
28850 - Torrejón de Ardoz, Madrid (ESPAÑA)
Tel: +34-91-626.80.60
Fax: +34-91-626.81.14


Reply via email to