221221 TIL

haremeat·2022년 12월 21일
0

Django

목록 보기
12/16
post-thumbnail
post-custom-banner

ValueError와 ValidationError

ValueError

공식상으로 틀린 값
이 value가 들어올 자리가 아닌데 들어온 상황

ValidationError

이 값은 들어와도 됨. 공식상으로 옳은 값

결론적으로 ValidationError는 기능적으로 무언가 추가적으로 하고 싶을 때 하는 것이고 (예를 들어 오류 알림 메시지)

ValueError같이 save()에서 막는 것은 어떠한 기능을 하고자 하기보다는 최후의 보루… 그냥 파이썬에서 막는 것.
개발자가 직접적으로 .save()를 호출하려 할 때 못하게 막는 것.

이게 가장 큰 차이점이다.

알고 있는 지식이어도
평소에 깊게 생각하지 않은 부분이면 놓치기 쉽다.

cursor pagination 오류

또 참신한 오류를 만났다.
와 기뻐~~

우리 툴에는 현재 작업하고 있는 데이터를 포함해 다음 데이터 n개를 미리 볼 수 있는 작은 화면이 있는데
첫 번째 데이터 작업화면에서는 그 데이터만 미리보기가 뜨지 않는다.
한 마디로 1번 데이터를 작업할 때만 데이터 미리보기가 자신을 제외한 2번~n번까지만 보이는 상황.
바로 다음 데이터로 이동하면 그때는 1번은 물론이고 본인까지 포함해서 다 잘 보인다.

사실 치명적인 버그는 아니었다.
유저들로부터 버그 리포트가 들어온 것도 아니었고
그냥 우리 개발팀에서 발견한 버그다.
다음 미리보기가 안 보인다면 문제였겠지만 어차피 현재 작업물은 작업창에 멀쩡히 보이니까 미리보기에 안 보여도 전혀 지장이 없다.

그래도 엄연히 되어야 하는 기능이 안 되는 거니까 고치긴 해야했다.
그리고 이런 버그 발견하면 이러는 이유가 뭔지 너무 궁금함

버그 원인

해당 cursor pagination의 커서 기준은 created. 즉 생성날짜이다.
페이지를 불러올 때 각각 커서가 다른 요청을 두 번 보내는데

  • 첫 번째 요청에는 자신의 created를 기준으로 created__lt를 가져온다.
  • 두 번째 요청에는 자신의 바로 직전 데이터의 created를 기준으로 created__gt를 가져온다.
    -> 결론 : 자기 자신을 포함하는 데이터는 두 번째 쿼리 가져올 때 가져오는데 0번 데이터는 직전 데이터가 없으므로 가져올 게 없다.

위 내용은 rest_framework.pagination의 pagination.py 파일에서 확인할 수 있다. 좀 더 자세히는 CursorPagination 클래스 안의 paginate_queryset 함수 안에 담겨져 있다.

if self.cursor.reverse != is_reversed:
    kwargs = {order_attr + '__lt': current_position}
else:
    kwargs = {order_attr + '__gt': current_position}

queryset = queryset.filter(**kwargs)

요렇게 정의되어있다.
두 번째 요청에는 reverse=True로 요청을 보낸다는 걸 알 수 있다.

해결방법

아무튼 어느 쪽이든 lte나 gte로 수정할 수 있다면 해결은 간단한데
문제는 drf의 CursorPagination 그 자체 코드를 건드려야 하는 부분이라
어떻게 해결할지 프론트팀 백엔드팀 같이 잠시 토론 시간을 가졌다.

결론은 프론트팀이 0번 데이터에 한해서만 현재 불러오는 작업물 response data를 이용해서 미리보기에 뿌려주는 식으로 결론났다.
어차피 현재 화면에서 뿌려주는 데이터가 곧 미리보기에 있는 정보와 같기 때문에...

고마워요 프론트팀!

profile
버그와 함께하는 삶
post-custom-banner

0개의 댓글