3

Pythonで使用xmlrpclibする場合、サーバー側のエラーはクライアント側からとして報告されますxmlrpclib.Faultdivision by zeroサーバー側のメソッド(を使用)でエラーが発生すると、通常SimpleXMLRPCServer、次のような出力が得られます。

xmlrpclib.Fault: <Fault 1: "<type 'exceptions.ZeroDivisionError'>:integer division or modulo by zero">

これは、エラーのタイプを記録するので便利ですが、現在はどこで発生したかを示しています。xmlrpclib.Faultメソッドを(?で)上書き/変更してSimpleXMLRPCServer、エラーを報告するようにするにはどうすればよいですか?たとえば、次のようになります。

xmlrpclib.Fault: <Fault 1: "<type 'exceptions.ZeroDivisionError'>:integer division or modulo by zero MODULE: myMethod.py  LINE: 657">

つまり、エラーが発生したモジュールの名前と行番号を含めることができます。カスタム例外を発生させることなく、サーバー側でそれを行うことは可能ですか?エラーはすべて、クライアント側でも同じ方法で報告する必要があります。

4

1 に答える 1

4

を使用するSimpleXMLRPCServerと、内部メソッドをオーバーライドして、生成されたインスタンス_marshaled_dispatchに情報を追加できます。Fault()

これは元の方法です。

def _marshaled_dispatch(self, data, dispatch_method = None, path = None):
    try:
        params, method = xmlrpclib.loads(data)

        # generate response
        if dispatch_method is not None:
            response = dispatch_method(method, params)
        else:
            response = self._dispatch(method, params)
        # wrap response in a singleton tuple
        response = (response,)
        response = xmlrpclib.dumps(response, methodresponse=1,
                                   allow_none=self.allow_none, encoding=self.encoding)
    except:
        # report low level exception back to server
        # (each dispatcher should have handled their own
        # exceptions)
        exc_type, exc_value = sys.exc_info()[:2]
        response = xmlrpclib.dumps(
            xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),
            encoding=self.encoding, allow_none=self.allow_none)
    return response

このメソッドをサブクラス化SimpleXMLRPCServer.SimpleXMLRPCServerしてオーバーライドできます。

import SimpleXMLRPCServer
import sys
import xmlrbclib

class VerboseFaultXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
    def _marshaled_dispatch(self, data, dispatch_method = None, path = None):
        try:
            params, method = xmlrpclib.loads(data)

            # generate response
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params)
            # wrap response in a singleton tuple
            response = (response,)
            response = xmlrpclib.dumps(response, methodresponse=1,
                                       allow_none=self.allow_none, encoding=self.encoding)
        except:
            # report low level exception back to server
            # (each dispatcher should have handled their own
            # exceptions)
            exc_type, exc_value, tb = sys.exc_info()
            while tb.tb_next is not None:
                tb = tb.tb_next  # find last frame of the traceback
            lineno = tb.tb_lineno
            code = tb.tb_frame.f_code
            filename = code.co_filename
            name = code.co_name
            response = xmlrpclib.dumps(
                xmlrpclib.Fault(1, "%s:%s FILENAME: %s LINE: %s NAME: %s" % (
                    exc_type, exc_value, filename, lineno, name)),
                encoding=self.encoding, allow_none=self.allow_none)
        return response

次に、VerboseFaultXMLRPCServerの代わりに使用しSimpleXMLRPCServer.SimpleXMLRPCServerます。

于 2013-01-21T17:01:58.283 に答える