๐[DRF] ์์ธ์ฒ๋ฆฌ๋ฅผ ๋ฐ์ฝ๋ ์ดํฐ๋ก?
try ~ except ์ ์ ๋ฐ์ฝ๋ ์ดํฐ๋ก ๊ด๋ฆฌํด๋ณด์!
ํ๋ก์ ํธ ์งํ ๋์ค, ์์ธ์ฒ๋ฆฌ
๋ก์ง์ ๋ฐ๋ก ๋ถ๋ฆฌํด์ ๊ด๋ฆฌํ๋ฉด view(or controller)
์์ ๋ฐ๋ณต์ ์ธ ์์ธ์ฒ๋ฆฌ ๋ก์ง์ด ํ์ ์์ด์ ธ ๊ฐ๋
์ฑ์ด ์ข์์ง๊ฑฐ ๊ฐ๋ค๋ ํผ๋๋ฐฑ์ ๋ฐ์๋ค!
๊ทธ๋์ django์์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋ค์ด, ํด๋น ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ์์ธ์ฒ๋ฆฌ๋ฅผ ์งํํ๋๋ก ์์ ํ๋ค!
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋๋๊ฑด ์ด๋ป๊ฒ ํ ๊น?
์ฐ์ , django์์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ๋ถํฐ ์์๋ณด์!
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ํ๋ ์ผ
result = func(*args, **kwargs)
return result
return wrapper
์ด๋ ๊ฒ ์์ฑํ๋ฉด, ๋ค๋ฅธ ํ์ผ์์ @my_decorator
๋ฅผ ์ ์ด ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ฉํ ์ ์๋ค.
@my_decorator
def say_hello(name):
return f"Hello, {name}!"
print(say_hello("Alice")) # "Calling function say_hello"์ "Hello, Alice!" ์ถ๋ ฅ
print(say_hello.__name__) # "say_hello" ์ถ๋ ฅ
print(say_hello.__doc__) # "Greet someone with their name." ์ถ๋ ฅ
๋ด๊ฐ ์ ์ด๋ณธ ๋ฐ์ฝ๋ ์ดํฐ!
def exception_handler(view: bool = False):
def exception_handler_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Card.DoesNotExist as e:
print(f"An error occurred in {func.__name__}: {e}")
return error_response("Invalid Card", status.HTTP_400_BAD_REQUEST)
except Game.DoesNotExist as e:
print(f"An error occuerd in {func.__name__}: {e}")
return error_response("Invalid Game", status.HTTP_400_BAD_REQUEST)
except Gametype.DoesNotExist as e:
print(f"An error occurred in {func.__name__}: {e}")
return error_response("Invalid Game Type", status.HTTP_400_BAD_REQUEST)
except AIAnswer.DoesNotExist as e:
print(f"An error occurred in {func.__name__}: {e}")
return error_response("Invalid AI Answer", status.HTTP_400_BAD_REQUEST)
except Exception as e:
print(f"An error occurred in {func.__name__}: {e}")
return error_response("Internal Server Error", status.HTTP_500_INTERNAL_SERVER_ERROR)
return wrapper
return exception_handler_decorator
def exception_handler(view: bool = False):
- views์์ ์ฌ์ฉํ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ํ๋ค.
view: bool = False
: ๋ง์ฝ ์ด ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ function์ด view์ธ์ง ์๋์ง ๊ฒ์ฌํ๋ค. ๊ธฐ๋ณธ ๊ฐ์ False
@wraps(func)
- Python์์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ํ ๋ ์ฌ์ฉํ๋ ๋๊ตฌ๋ก,
functools
๋ชจ๋์์ ์ ๊ณต๋๋ค. - ๋ฐ์ฝ๋ ์ดํธ๋ ํจ์๊ฐ ์๋
ํจ์์ ์ด๋ฆ
,๋ฌธ์ ๋ฌธ์์ด(docstring)
,์ฃผ์
, ๋ฐ๊ธฐํ ์์ฑ
์ ์์ง ์๋๋ก ํ๋ค.
- Python์์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ ์ํ ๋ ์ฌ์ฉํ๋ ๋๊ตฌ๋ก,
def wrapper(*args, **kwargs)
wrapper
ํจ์๋ ์๋ ํจ์(func
)๋ฅผ ๋ํํ์ฌ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ค.*args
์**kwargs
๋ ์๋ ํจ์์ ๋ชจ๋ ์ธ์๋ฅผ ๊ทธ๋๋ก ๋ฐ๋๋ค.- ๋ณธ๊ฒฉ์ ์ธ ์์ธ์ฒ๋ฆฌ ๋ก์ง์ ์ํํ๋ค.
try ~ except
return func(*args, **kwargs)
: ์๋ ํจ์๋ฅผ ํธ์ถํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.- ์ดํ์๋ ๋ฐ์ดํฐ ์กด์ฌ ์ฌ๋ถ์ ์์ธ์ฒ๋ฆฌ์ ๊ทธ ์ธ์ ์์ธ๋ ์ ๋ค๋ฆญํ๊ฒ ๋ฐ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ค.
๋ด๊ฐ ๋ง๋ ๋ฐ์ฝ๋ ์ดํฐ์์ ์ด error_response๋ ๋ญ์ง?
from rest_framework import status
from rest_framework.response import Response
def error_response(error: str, status_code: int):
return Response({"error": error}, status_code)
- ์ธ์๋ก
์๋ฌ ๋ฉ์์ง(error)
์HTTP ์ํ ์ฝ๋(status_code)
๋ฅผ ๋ฐ๋๋ค. - ์ฌ์ฉ์์๊ฒ๋
{"error": error}
ํฌ๋ฉง์ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ์ํ ์ฝ๋๋ฅผ ์ ๋ฌํ๋ค.
๋ฐ์ฝ๋ ์ดํฐ ๋์ ์์?
ํ๋์ ๋์(ํจ์)์ ์ํํ ๋, ์ฌ๋ฌ ๊ฐ์ง์ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ทธ๋ฐ๋ฐ, ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ๋ถ์ด์์ผ๋ฉด ์ด ๋ฐ์ฝ๋ ์ดํฐ๋ค์ด ์ด๋ค ์์๋ฅผ ๊ฐ๊ณ ๋์ํ๋์ง๋ฅผ ์์์ผ ๋ด๊ฐ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ง๋ค์ด ์ ์ ํ๊ฒ ์ธ ์ ์๋ค!
์์ ์์๋ฅผ ๋ณด๋ฉด ์ดํด๊ฐ ์ฝ๋ค!
ํจ์๊ฐ ๋จผ์ ์คํ๋๊ณ , ์์ ์๋ ๋ฐ์ฝ๋ ์ดํฐ โ ๊ทธ ์์ ๋ฐ์ฝ๋ ์ดํฐ ์์ผ๋ก ๋์ํ๊ฒ ๋๋ค.
์ด ํฌ์คํ ์์ ์์ฑํ ์์๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ์ฝ๋ ์ดํฐ์์ผ๋, ํจ์๊ฐ ๋์ํ๊ณ ๊ทธ ๊ฒฐ๊ณผ์ ๋ํ ์์ธ์ฒ๋ฆฌ๋ฅผ ๋ฐ๋ก ์ฒ๋ฆฌํด์ผํ๋ฏ๋ก, ํจ์ ๋ฐ๋ก ์์ ์ ์ธํ๋ค.
๋๊ธ๋จ๊ธฐ๊ธฐ