error_catch.py 5.4 KB
Newer Older
F
felixhjh 已提交
1 2 3 4 5
import sys 
import enum 
import os 
import logging 
import traceback
6
#from paddle_serving_server.pipeline import ResponseOp
F
felixhjh 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19
import threading
import inspect
import traceback
import functools
import re
from .proto import pipeline_service_pb2_grpc, pipeline_service_pb2

_LOGGER = logging.getLogger(__name__) 

class CustomExceptionCode(enum.Enum): 
    """
    Add new Exception
    """
20 21 22 23 24
    INTERNAL_EXCEPTION = 500
    TYPE_EXCEPTION = 501
    TIMEOUT_EXCEPTION = 502
    CONF_EXCEPTION = 503
    PARAMETER_INVALID = 504
F
felixhjh 已提交
25 26

class CustomException(Exception):
27
    def __init__(self, exceptionCode, errorMsg, isSendToUser=False):
F
felixhjh 已提交
28 29 30
        super().__init__(self)
        self.error_info = "\n\texception_code: {}\n"\
                          "\texception_type: {}\n"\
31
                          "\terror_msg: {}\n"\
F
felixhjh 已提交
32 33
                          "\tis_send_to_user: {}".format(exceptionCode.value,
                          CustomExceptionCode(exceptionCode).name, errorMsg, isSendToUser)
F
felixhjh 已提交
34 35 36 37 38 39 40 41 42 43
    
    def __str__(self):
        return self.error_info

class ErrorCatch():
    def __call__(self, func):
        if inspect.isfunction(func) or inspect.ismethod(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                try:
44
                    res = func(*args, **kw)
F
felixhjh 已提交
45
                except CustomException  as e:
46
                    resp = pipeline_service_pb2.Response()
F
felixhjh 已提交
47 48
                    _LOGGER.error("{}\tFunctionName: {}{}".format(traceback.format_exc(), func.__name__, args))
                    split_list = re.split("\n|\t|:", str(e))
49 50
                    resp.err_no = int(split_list[3])
                    resp.err_msg = "{}\n\tClassName: {}, FunctionName: {}, ErrNo: {}".format(str(e), func.__class__ ,func.__name__, resp.err_no)
F
felixhjh 已提交
51
                    is_send_to_user = split_list[-1]
52 53 54
                    if bool(is_send_to_user) is True:
                         return (None, resp)
                    #    self.record_error_info(error_code, error_info)
F
felixhjh 已提交
55
                    else:
56 57 58 59 60 61 62 63 64 65 66 67 68
                        raise("init server error occur")
                except Exception as e:
                    resp = pipeline_service_pb2.Response()
                    _LOGGER.error("{}\tFunctionName: {}{}".format(traceback.format_exc(), func.__name__, args))
                    resp.err_no = 404
                    resp.err_msg = "{}\n\tClassName: {} FunctionName: {}, ErrNo: {}".format(str(e), func.__class__ ,func.__name__, resp.err_no)
                    return (None, resp)
                    # other exception won't be sent to users.
                else:
                    resp = pipeline_service_pb2.Response()
                    resp.err_no = 200
                    resp.err_msg = ""
                    return (res, resp)
F
felixhjh 已提交
69

F
felixhjh 已提交
70 71 72 73 74
            return wrapper
    
    def record_error_info(self, error_code, error_info):
        ExceptionSingleton.set_exception_response(error_code, error_info)

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
def ParamChecker(function):
    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        # fetch the argument name list.
        parameters = inspect.signature(function).parameters
        argument_list = list(parameters.keys())

        # fetch the argument checker list.
        checker_list = [parameters[argument].annotation for argument in argument_list]

        # fetch the value list.
        value_list =  [inspect.getcallargs(function, *args, **kwargs)[argument] for argument in inspect.getfullargspec(function).args]

        # initialize the result dictionary, where key is argument, value is the checker result.
        result_dictionary = dict()
        for argument, value, checker in zip(argument_list, value_list, checker_list):
            result_dictionary[argument] = check(argument, value, checker, function)

        # fetch the invalid argument list.
        invalid_argument_list = [key for key in argument_list if not result_dictionary[key]]

        # if there are invalid arguments, raise the error.
        if len(invalid_argument_list) > 0:
            raise CustomException(CustomExceptionCode.PARAMETER_INVALID, "invalid arg list: {}".format(invalid_argument_list))

        # check the result.
        result = function(*args, **kwargs)
        checker = inspect.signature(function).return_annotation
        if not check('return', result, checker, function):
            raise CustomException(CustomExceptionCode.PARAMETER_INVALID, "invalid return type")

        # return the result.
        return result
    return wrapper


def check(name, value, checker, function):
    if isinstance(checker, (tuple, list, set)):
        return True in [check(name, value, sub_checker, function) for sub_checker in checker]
    elif checker is inspect._empty:
        return True
    elif checker is None:
        return value is None
    elif isinstance(checker, type):
        return isinstance(value, checker)
    elif callable(checker):
        result = checker(value)
        return result

class ParamVerify(object):
    @staticmethod
    def int_check(c, lower_bound=None, upper_bound=None):
        if not isinstance(c, int):
            return False
        if isinstance(lower_bound, int) and isinstance(upper_bound, int):
            return c >= lower_bound and c <= upper_bound
        return True

    @staticmethod
    def file_check(f):
        if not isinstance(f, str):
            return False
        if os.path.exist(f):
            return True
        else:

            return False

F
felixhjh 已提交
143
ErrorCatch = ErrorCatch()