아직도 Return 해서 에러 핸들링 하시나요?

Jongma·2022년 1월 8일
0
post-thumbnail

클린 코드를 읽고 에러 핸들링 로직을 리팩토링한 내용을 정리했습니다.

Boolean 값을 반환해서 에러 핸들링하기

먼저 예전에 제가 작성한 코드를 한번 보도록 하겠습니다.

def check_excel_datas_verify(self, index, row):
    try:
        for row_value, column in zip(row, self.column_list):
            row_dict = {}
            if column == self.lang("HostExporter.headTitles.text.2"):
                if self.check_host_type(row_value, index):
                    self.except_count += 1
                    return False
                row_dict["HOSTTYPE"] = row_value
                ...
    except Exception as err:
        logger.write(err)
        raise Exception(err)


def check_host_type(self, row_value, index):
    sql = "SELECT COUNT(*) FROM HOST_TYPE WHERE HOSTTYPE = '{0}'".format(row_value)
    result = self.db.execute(sql)
    if not result[0]:
        msg = "[CHECK_HOST_TYPE]no:{0}, Host type doesn't exists.".format(index)
        logger.write(msg)
        return True
    return False

위 코드는 엑셀에 입력한 값으로 호스트 정보를 웹에 등록하는 기능 중에서 엑셀에 작성한 HOST_TYPE 값이 유효한 값으로 들어왔는지 검증하는 로직입니다.

def check_host_type(self, row_value, index):
    sql = "SELECT COUNT(*) FROM HOST_TYPE WHERE HOSTTYPE = '{0}'".format(row_value)
    result = self.db.execute(sql)
    if not result[0]:
        msg = "[CHECK_HOST_TYPE]no:{0}, Host type doesn't exists.".format(index)
        logger.write(msg)
        return True
    return False

check_host_type 메소드부터 자세하게 확인해보겠습니다.
result[0] 값이 없다면 호스트 타입이 없다고 판단하고 True 값을 반환해주고 있습니다.

그리고 호출 부 메소드에서는 if 문으로 결과를 확인해서 만약 True라면 실패라고 판단해서 False 값을 반환해주고 있습니다.

위 로직에서는 에러를 핸들링하기 위해서 하위 메소드 계층에서 Boolean 값 반환을 하고 있습니다. 그리고 모든 상위 계층에서는 if 문으로 판단해서 실패에 따른 로직을 작성했습니다.

def check_excel_datas_verify(self, index, row):
    try:
        for row_value, column in zip(row, self.column_list):
            row_dict = {}
            if column == self.lang("HostExporter.headTitles.text.2"):
                if self.check_host_type(row_value, index):
                    self.except_count += 1
                    return False
                row_dict["HOSTTYPE"] = row_value
                ...
    except Exception as err:
        logger.write(err)
        raise Exception(err)

위와 같은 형태로 작성하게 되면 호출하는 쪽의 코드가 복잡해지는 문제가 있습니다.

왜냐하면 성공 실패에 대한 여부를 상위 메소드에서 if 문으로 확인해줘야 하기 때문입니다. 따라서 오류코드나 Boolean 값을 반환해서 확인하는 대신에 예외를 발생시키는 게 훨씬 가독성 높은 코드를 작성할 수 있습니다.

예외 발생시켜서 에러 핸들링하기

그러면 Boolean 값을 반환하는 대신에 예외를 발생시켜서 리팩토링한 코드를 확인해봅시다.

def check_host_type(self, row_value, index):
    sql = f"SELECT COUNT(*) FROM HOST_TYPE WHERE HOSTTYPE = '{row_value}'"
    result = self.db.execute(sql)

    if not result[0]:
        err_msg = "[CHECK_HOST_TYPE]no:{0}, Host type doesn't exists.".format(index)
        raise Exception(err_msg)

위 코드를 확인해보면 결과를 확인하는 로직은 동일하지만 이후에 Boolean 값을 반환하는 값에서 예외를 발생하도록 수정되었습니다. 이렇게 예외를 반환하게 되면 아래와 같이 상위호출 부에서는 더 이상 if 문으로 값으로 성공 실패 여부를 판단하지 않아도 됩니다.

또한, 실패했을 경우의 로직을 validation 로직 내부에 넣지 않아도 되기 때문에 코드의 응집도가 높아집니다.

def check_excel_datas_verify(self, index, row):
    try:
        validated_row = {}
        for row_value, column in zip(row, self.column_list):
            if column == self.lang("HostExporter.headTitles.text.2"):
                self.check_host_type(row_value, index)
                validated_row["HOSTTYPE"] = row_value
                ...
    except Exception as err:
        self.except_count += 1
        raise Exception(err)

이처럼 오류코드나 특정 값을 반환해서 에러 처리하지 않고 예외 발생을 통해서 예외 처리를 하게 되면 위와 같이 호출 부 로직의 가독성 또한 좋아지는 것을 확인할 수 있습니다.

0개의 댓글