프로그래밍/Python

[Python] 발생한 Exception의 클래스를 확인하는 방법은?

채윤아빠 2023. 9. 19. 14:49
728x90
반응형

발생 상황

데이터베이스에 연결하여 데이터를 추가(insert)하는 작업에서 Exception이 발생하였습니다.

Exception이 발생한 원인은 테이블에 유일키가 있었는데, 중복된 값을 추가하여 "IntegrityError" 오류가 발생한 것이었습니다.

정확하게 IntegrityError만 except 처리를 하면 되겠지만, "except Exception as e:" 구문 하나로 해결할 수 없나 하는 생각에 그럼 발생한 Exception의 클래스를 확인하여 "IntegrityError" 오류만 별도 처리하면 되지 않을까? 하는 생각에 관련 자료를 찾아보게 되었습니다.


Exception의 클래스 이름 확인 방법

참고자료를 보면, Exception의 클래스 이름 확인 방법은 간단하게 다음과 같이 할 수 있습니다.

try
    .
    .
    .
except Exception as exception:
    assert type(exception).__name__ == 'NameError'
    assert exception.__class__.__name__ == 'NameError'
    assert exception.__class__.__qualname__ == 'NameError'

그러나 여기서 생각해볼 점은, "IntegrityError" 오류는 동일 이름의 오류가 여러 개가 있을 수 있으므로 보다 정확하게 처리하기 위해서는 모듈의 이름까지 확인해야만 합니다.
(pymysql.err.IntegrityError, sqlalchemy.exc.IntegrityError, django.db.IntegrityError, mysql.connector.errors, ...)

def get_full_class_name(obj):
    module = obj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return obj.__class__.__name__
    return module + '.' + obj.__class__.__name__

try
    .
    .
    .
except Exception as exception:
    assert get_full_class_name(exception) == 'mysql.connector.errors.IntegrityError'

IntegrityError 오류를 except 구문으로 처리하는 방법

정석적으로 오류를 처리하고자 한다면 "from ... import ..."로 오류 클래스를 가져와서 "except" 구분으로 처리해야 합니다.

데이터베이스 연결을 위하여 "mysql-connector-python", "sqlalchemy"를 이용한다면, 다음과 같이 하시면 됩니다.

from mysql.connector.errors import IntegrityError

try:
    .
    .
    .
except IntegrityError as ie: 
    return { "result_code":-1001, "result_message": "duplicated error" }
except Exception as e: 
    return { "result_code":-1000, "result_message": f"{e!r}" }

"IntegrityError" 오류에 대하여 추가로 주의할 점은 오류 이름 그대로 데이터베이스 무결성(Integrity)을 훼손하는 쿼리로 인하여 발생한 문제이므로, 중복된 데이터 삽입 때문인지 필수 항목에 값을 넣지 않은 것인지는 오류 메시지를 확인해야만 합니다.


참고자료