1

標準ライブラリ(xmlrpclib+ SimpleXMLRPCServerPython2およびxmlrpc.serverPython3)は、すべてのエラー(使用法エラーを含む)をPython例外として報告します。これは、パブリックサービスには適していません。例外文字列は、Pythonの知識がないと簡単に理解できないことが多く、機密情報が公開される可能性があります。これを修正するのは難しいことではありませんが、私は車輪の再発明を避けたいと思っています。エラー報告が優れたサードパーティのライブラリはありますか?私は、すべての使用法エラーの適切な障害メッセージと、内部エラーを報告するときに内部を非表示にすることに関心があります(これはロギングを使用した方が適切です)。

xmlrpclibすでにそのようなエラーの定数NOT_WELLFORMED_ERRORUNSUPPORTED_ENCODINGありINVALID_ENCODING_CHARます:、、、、、、、、。INVALID_XMLRPCMETHOD_NOT_FOUNDINVALID_METHOD_PARAMSINTERNAL_ERROR

4

2 に答える 2

1

ライブラリ固有の問題はないと思います。ライブラリまたはフレームワークを使用する場合、通常、すべてのエラーをトラップし、どこかにログを記録して、「おっと、問題が発生しています。エラー番号 100 で x@x.com に連絡して、何を教えてください。あなたがした。」したがって、失敗しやすいエントリ ポイントを try/catch でラップし、汎用ロガーを作成して、すぐに始められます...

于 2009-10-22T15:47:13.863 に答える
1

私の要件を満たす準備が整ったライブラリがないように見えるため、独自の実装になりました。

class ApplicationError(Fault):

    def __init__(self, exc_info):
        Fault.__init__(self, xmlrpclib.APPLICATION_ERROR,
                       u'Application internal error')


class NotWellformedError(Fault):

    def __init__(self, exc):
        Fault.__init__(self, xmlrpclib.NOT_WELLFORMED_ERROR, str(exc))


class UnsupportedEncoding(Fault):

    def __init__(self, exc):
        Fault.__init__(self, xmlrpclib.UNSUPPORTED_ENCODING, str(exc))


# XXX INVALID_ENCODING_CHAR is masked by xmlrpclib, so the error code will be
# INVALID_XMLRPC.
class InvalidRequest(Fault):

    def __init__(self, message):
        ault.__init__(self, xmlrpclib.INVALID_XMLRPC, message)


class MethodNotFound(Fault):

    def __init__(self, name):
        Fault.__init__(self, xmlrpclib.METHOD_NOT_FOUND,
                       u'Method %r is not supported' % name)


class WrongMethodUsage(Fault):

    def __init__(self, message):
        Fault.__init__(self, xmlrpclib.INVALID_METHOD_PARAMS, message)


class WrongType(Fault):

    def __init__(self, arg_name, type_name):
        Fault.__init__(self, xmlrpclib.INVALID_METHOD_PARAMS,
                       u'Parameter %s must be %s' % (arg_name, type_name))


class XMLRPCDispatcher(SimpleXMLRPCDispatcher, XMLRPCDocGenerator):

    server_name = server_title = 'Personalization center RPC interface'
    server_documentation = 'Available methods'

    def __init__(self, methods):
        SimpleXMLRPCDispatcher.__init__(self, allow_none=True, encoding=None)
        self.register_instance(methods)
        self.register_multicall_functions()
        #self.register_introspection_functions()

    def _dispatch(self, method_name, args):
        if self.funcs.has_key(method_name):
            method = self.funcs[method_name]
        else:
            method = self.instance._getMethod(method_name)
        arg_names, args_name, kwargs_name, defaults = \
                                                inspect.getargspec(method)
        assert arg_names[0]=='self'
        arg_names = arg_names[1:]
        n_args = len(args)
        if not (args_name or defaults):
            if n_args!=len(arg_names):
                raise WrongMethodUsage(
                    u'Method %s takes exactly %d parameters (%d given)' % \
                                (method_name, len(arg_names), n_args))
        else:
            min_args = len(arg_names)-len(defaults)
            if len(args)<min_args:
                raise WrongMethodUsage(
                    u'Method %s requires at least %d parameters (%d given)' % \
                                (method_name, min_args, n_args))
            if not args_name and n_args>len(arg_names):
                raise WrongMethodUsage(
                    u'Method %s requires at most %d parameters (%d given)' % \
                                (method_name, len(arg_names), n_args))
        try:
            return method(*args)
        except Fault:
            raise
        except:
            logger.exception('Application internal error for %s%r',
                             method_name, args)
            raise ApplicationError(sys.exc_info())

    def dispatch(self, data):
        try:
            try:
                args, method_name = xmlrpclib.loads(data)
            except ExpatError, exc:
                raise NotWellformedError(exc)
            except LookupError, exc:
                raise UnsupportedEncoding(exc)
            except xmlrpclib.ResponseError:
                raise InvalidRequest('Request structure is invalid')
            method_name = method_name.encode('ascii', 'replace')
            result = self._dispatch(method_name, args)
        except Fault, exc:
            logger.warning('Fault %s: %s', exc.faultCode, exc.faultString)
            return xmlrpclib.dumps(exc)
        else:
            try:
                return xmlrpclib.dumps((result,), methodresponse=1)
            except:
                logger.exception('Application internal error when marshalling'\
                                 ' result for %s%r', method_name, args)
                return xmlrpclib.dumps(ApplicationError(sys.exc_info()))


class InterfaceMethods:

    def _getMethod(self, name):
        if name.startswith('_'):
            raise MethodNotFound(name)
        try:
            method = getattr(self, name)
        except AttributeError:
            raise MethodNotFound(name)
        if not inspect.ismethod(method):
            raise MethodNotFound(name)
        return method
于 2009-10-22T16:43:41.597 に答える