[ Python ] decorator로 Error 정리해서 출력하기

2020. 1. 31. 17:57분석 Python/구현 및 자료

광고 한번만 눌러주세요. 블로그 운영에 큰 힘이 됩니다!

파이썬 코드를 돌리다 에러가 나게 되면 다음과 같이 에러가 보일 것이다.

이런 식으로 Traceback 코드로 나오게 된다.
의미는 error_test.py에서 module 안에 ho라는 def에 있는 sub라는 def에서 TypeError가 났다고 할 수 있다.
만약에 더 복잡하게 된다면, 에러를 확인할 수는 있지만, 보기 쉽지 않을 것이다.
그래서 이러한 점을 해결하기 위해 decorator를 활용해서 에러메시지를 좀 더 보기 쉽게 만들어봤다.

from functools import wraps
import datetime
import time

def errorcheck(original_function):
    import logging
    import traceback
    import sys
    log = logging.getLogger('Error')
    log.setLevel(logging.DEBUG)
    log.propagate = True
    formatter = logging.Formatter("Error : %(asctime)s;\n%(message)s", "[%Y/%m/%d] %H:%M:%S")
    streamHandler = logging.StreamHandler()
    streamHandler.setFormatter(formatter)
    log.addHandler(streamHandler)
    @wraps(original_function)  #1
    def wrapper(*args, **kwargs):
        try :
            return original_function(*args, **kwargs)
        except Exception as e :
        
            exc_type, exc_obj, tb = sys.exc_info()
            formatted_lines = traceback.format_exc().splitlines()
            num = ([idx for idx , i 
                    in enumerate(formatted_lines) 
                    if re.search(" line ", i) is not None ][-1])
            s  = [line.split(",") for line in formatted_lines[num:]]
            import itertools
            merged = list(itertools.chain(*s))
            finalerror = "\n".join([string.strip() for string in merged])
            func_name = original_function.__name__
            errors =  traceback.extract_stack()
            errors = ("".join(
                [f"Where : {str(i).split('FrameSummary file ')[1].split(',')[0]} \n Line : {str(i).split('FrameSummary file ')[1].split(',')[1]}\n {'--'*30} \n" 
                 for i in errors[:-1]]))
            print(f"{'*'*15} Search {'*'*15} \n {errors}")
            log.error(f"{'=='*20}\n{finalerror}\n{'=='*20}")
            sys.exit(1)
    return wrapper
    
class test :
    
    def sub(self,a,b) :
        return a - b
    @errorcheck
    def ho(self, a, b) :
        return self.sub(a,b)
                      
                      
test().ho(5,"1")

마지막 에러가 중요하니 그 부분만 빼는 식으로 하고 강조했다.
그래서 error_test.py에 line 44에 있는 sub라는 함수에서 a-b가 문제가 발생했다.
에러는 TypeError 이다를 의미한다.

도움이 된다고 생각하시면 광고 클릭 : ) !

 

728x90