클린 코드: 에러 핸들링
1. 오류 코드 보다는 예외(Exception)을 사용한다.
try, except를 사용하면 오류인지 확인하는 불필요한 로직을 줄일 수 있다.
### as-is
from enum import Enum
class ErrorCodes(Enum):
VALUE_ERROR="VALUE_ERROR"
def we_can_raise_error():
...
return ERROR_CODES.VALUE_ERROR
def use_ugly_function():
result = we_can_occur_error()
if result == ErrorCodes.VALUE_ERROR:
# 처리 코드
...
### to-be
def we_can_raise_error():
if ...
raise ValueError("에러 발생")
def use_awesome_function():
try:
we_can_occur_error()
...
except ValueError as e:
# 에러 처리 로직
2. 예외 클래스를 잘 정의한다.
- 내장된 built in Exception을 잘 활용한다. (파이썬 : https://docs.python.org/ko/3/library/exceptions.html)
- 상황에 맞게 커스텀 Exception을 만들어 사용한다.
class CustomException(Exception):
...
class WithParameterCustomException(Exception):
def __init__(self, msg, kwargs):
self.msg = msg
self.kwargs = kwargs
def __str__():
return f"message {self.msg} with parameter {self(self.kwargs)}"
raise WithParameterCustomException("문제가 있습니다", {"name": "grab"})
3. 에러 핸들링
같은 수준의 로직은 한곳으로 모아 Exception 처리한다.
### as-is
def act_1():
try:
we_can_raise_error1()
...
except:
#handling
def act_2():
try:
we_can_raise_error2()
...
except:
#handling
def act_3():
try:
we_can_raise_error3()
...
except:
#handling
# 에러가 날 지점을 한눈에 확인할 수 없습니다.
# act_1이 실패하면 act_2가 실행되면 안 된다면? 핸들링하기 어려워집니다.
def main():
act_1()
act_2()
act_3()
### to-be
def act_1():
we_can_raise_error1()
...
def act_2():
we_can_raise_error2()
...
def act_3():
we_can_raise_error3()
...
# 직관적이며 에러가 날 지점을 확인하고 처리할 수 있습니다.
# 트랜잭션같이 한 단위로 묶여야하는 처리에도 유용합니다.
def main():
try:
act_1()
act_2()
act_3()
except SomeException1 as e1:
...
except SomeException2 as e2:
...
except SomeException2 as e3
...
finally:
...
** 핸들링하는 법
# GOOD
def use_awesome_function():
try:
we_can_raise_error()
...
except Exception as e:
logging.error(...) # Error Log 남기기
notify_error(...) # 예측 불가능한 외부 I/O 이슈라면 회사 내 채널에 알리기(이메일, 슬랙 etc)
raise OtherException(e) # 만약 이 함수를 호출하는 다른 함수에서 추가로 처리해야 한다면 에러를 전파하기
finally:
... #에러가 발생하더라도 항상 실행되어야 하는 로직이 있다면 finally 문을 넣어주기
<참고>
'# Development > Methodologies' 카테고리의 다른 글
[REST API] API 문서 작성 (0) | 2023.06.14 |
---|---|
[성능 테스트] Throughput(TPS), Latency (0) | 2023.02.02 |
[클린 코드] 클래스 (0) | 2023.01.31 |
[클린 코드] 함수 (0) | 2023.01.31 |