오늘 우연찮게 진행중인 프로젝트에서 오류를 발견했다.
현재 우리 프로젝트의 가장 열혈 사용자가 본인이다보니 이미 프로젝트에 저장된 스크랩이 꽤 있다. 그래서 여태껏 스크랩 추가, 삭제가 정상적으로 동작한다고 굳게 믿고 있었는데...!
오늘 다른 팀원의 계정으로 스크랩을 추가/삭제해보다가 스크랩이 하나도 없는 상태에서 스크랩을 추가하거나 한 개 있는 스크랩이 삭제되면 오류가 발생하는 것을 깨달았다.
스크랩의 유무
가 문제선택된 상태
로 만드는 과정을 추가해두었다. 해당 오류 메시지는 아직 스크랩 목록을 전달받지 못해 첫번째 스크랩이 '선택'되지 않았는데 먼저 첫 번째 스크랩에 대한 렌더링을 진행하려 할 때 발생했다.export const useDeleteScrap = () => {
const queryClient = useQueryClient();
return useMutation(fetchDeleteScrap, {
onSuccess: () => {
queryClient.invalidateQueries(['scraps']);
useDefaultSnackbar('스크랩이 삭제되었습니다.', 'success');
},
onError: (error) => {
Sentry.captureException(error);
useDefaultSnackbar('스크랩 삭제에 실패하였습니다.', 'error');
},
useErrorBoundary: false,
});
}
이는 수정하기 전 코드인데, 스크랩 삭제를 성공하면 invalidateQueries를 통해 스크랩 목록을 다시 조회하도록 한다. 추가에도 동일한 코드가 삽입되어 있다.
스크랩이 하나 존재하는 템플릿에서 해당 스크랩을 삭제하면 스크랩이 없는 템플릿으로 변경되어야 한다. 하지만, 현재 스크랩 페이지 코드는 스크랩 개수를 요청하여 0개일 때는 스크랩 없는 템플릿을 리턴하고, 아닐 때에는 타입에 맞추어 스크랩 목록을 리턴하도록 짜여져있다. 따라서, 스크랩 목록만 재조회하면, 해당 템플릿은 이미 스크랩이 존재하는 템플릿으로 분류되어 있는 상태이므로 스크랩이 없는 페이지에서 '선택 상태'를 만들려고 시도하는 것이다.
상황적인 설명이 함께 하느라 말이 길어졌지만, 결론적으로는 코드 한 줄을 추가하여 해결했다. 👍
export const usePostCreateScrap = () => {
const queryClient = useQueryClient();
const isExistScrap = (error: any) => error.message === 'BR002';
return useMutation(fetchPostCreateScrap, {
onSuccess: () => {
// 스크랩 개수 조회 invalidate 코드 삽입
queryClient.invalidateQueries(['scrapCount']);
queryClient.invalidateQueries(['scraps']);
useDefaultSnackbar('스크랩이 생성되었습니다', 'success');
},
onError: (error) => {
Sentry.captureException(error);
isExistScrap(error)
? useDefaultSnackbar('이미 존재하는 스크랩입니다.', 'error')
: useDefaultSnackbar('스크랩 생성에 실패하였습니다.', 'error');
},
useErrorBoundary: false,
});
}
이제 이 타이밍 즈음에 후기를 적고 싶었으나 해당 문제를 해결한 이후 새로운 문제가 발생했다. 이 문제는 해결하면 2탄으로 돌아와야지...