T.I.L May 26, 2023 (status 400 error bad request 해결과정)

2023. 5. 26. 17:37T.I.L (Today_I_Learned)

문제점


악명높은 javascript를 팀 프로젝트 진행중 사용하게 되었습니다.

오늘의 문제는 크게 2가지가 있었습니다.

 

1. json형식에 대한 인지 부족으로 인해 발생한 error 

2. Django 모델의 필드가 어떠한 모델 필드를 사용하고 있는지 확인하지 못하고 잘못된 자료형을 보내주어서 발생한 error

 

아래의 코드는 error를 발생시킨 코드 입니다. 무엇이 문제인지 맞춰보시죠

updateBtn.addEventListener("click", async function () {
        const { value: updatedContent } = await Swal.fire({
            title: '후기 수정',
            input: 'textarea',
            inputLabel: '후기 내용',
            inputValue: review.content,
            showCancelButton: true,
            inputValidator: (value) => {
                if (!value) {
                    return '후기 내용을 입력해주세요.';
                }
            }
        });

        if (updatedContent) {
            const { value: updatedRating } = await Swal.fire({
                title: '평점 수정',
                input: 'range',
                inputLabel: '평점',
                inputAttributes: {
                    min: 1.0,
                    max: 5.0,
                    step: 0.5
                },
                inputValue: review.rating,
                showCancelButton: true,
                inputValidator: (value) => {
                    if (!value) {
                        return '평점을 선택해주세요.';
                    }
                }
            });

            if (updatedRating) {
                const response = await fetch(`${backend_base_url}/reviews/${review.movie[0]}/${review.id}/`, {
                    method: "PUT",
                    headers: {
                        "Content-Type": "application/json",
                        "Authorization": "Bearer " + localStorage.getItem("access")
                    },
                    body: JSON.stringify({
                        content: updatedContent,
                        rating: updatedRating
                    })
                });

 

 

해결 과정 & 해결


1. json 형식을 맞추지 않아 발생한 오류

const response = await fetch(`${backend_base_url}/reviews/${review.movie[0]}/${review.id}/`, {
    method: "PUT",
    headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + localStorage.getItem("access")
    },
    body: JSON.stringify({
        content: updatedContent,
        rating: updatedRating
    })
});

위 코드를 보시면 뭔가 잘못된 것을 아실 수 있으실 겁니다.

  1. status 400 bad request 오류를 직면
  2. status 400 bad request 오류라면 클라이언트의 요청 방식이 잘못 되어서 발생한 오류일 가능성 높음
  3. 작성한 fetch 코드들 중 에러를 발생 시키지 않은 다른 POST 요청 방식이나 PUT 요청 방식의 코드를 찾아봄

 

문제는 아래의 코드 부분입니다.

body: JSON.stringify({
    content: updatedContent,
    rating: updatedRating
})

body 부분에 실어서 보낼 값들의 양식을 잘못 작성한 것을 알 수 있습니다.

JSON형식으로 통신을 할 때에는 key값에 ""를 붙여서 코드를 작성해 주어야 합니다.

 

해결

body: JSON.stringify({
    "content": updatedContent,
    "rating": floatRating
})

 

2. request 요청을 보낼때 모델 필드의 자료형을 확인하지 못해 발생한 error

if (updatedContent) {
    const { value: updatedRating } = await Swal.fire({
        title: '평점 수정',
        input: 'range',
        inputLabel: '평점',
        inputAttributes: {
            min: 1,
            max: 5,
            step: 1
        },
        inputValue: review.rating,
        showCancelButton: true,
        inputValidator: (value) => {
            if (!value) {
                return '평점을 선택해주세요.';
            }
        }
    });

    if (updatedRating) {
        const response = await fetch(`${backend_base_url}/reviews/${review.movie[0]}/${review.id}/`, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + localStorage.getItem("access")
            },
            body: JSON.stringify({
                content: updatedContent,
                rating: updatedRating
            })
        });
class Review(models.Model):
                            .
                            .
                            
    rating = models.FloatField("평점", choices=RATING_CHOICES)
    						
                            .
                            .

 

 

해결 과정

  1. json 형식으로 변환을 했지만 여전히 status 400 에러가 발생
  2. 또 어떠한 요청을 잘못 보냈는지 찾던 중 Django의 모델 필드를 확인하게 됨
  3. rating 필드는 FloatField로 실수형 값을 넣어줘야 했던 것
  4. 계속해서 정수형 값을 보내줬던 것이 error의 원인

 

해결

if (updatedContent) {
    const { value: updatedRating } = await Swal.fire({
        title: '평점 수정',
        input: 'range',
        inputLabel: '평점',
        inputAttributes: {
            min: 1,
            max: 5,
            step: 0.5
        },
        inputValue: review.rating,
        showCancelButton: true,
        inputValidator: (value) => {
            if (!value) {
                return '평점을 선택해주세요.';
            }
        }
    });

    if (updatedRating) {
        // rating 값이 무조건 float형으로 들어가야 하므로 parseFloat과 toFixed(1)을 활용해 소수점 아래 1자리로 값을 제한합니다.
        const floatRating = parseFloat(updatedRating).toFixed(1);
        const response = await fetch(`${backend_base_url}/reviews/${review.movie[0]}/${review.id}/`, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + localStorage.getItem("access")
            },
            body: JSON.stringify({
                "content": updatedContent,
                "rating": floatRating
            })
        });

 

알게된 것


1. status 에러를 마주하면 차분히 에러의 의미를 생각해 볼 것(에러에 답이 있었음)

2. 무엇이 문제일지 디버깅을 할 때 개발자 도구의 Network를 활용할 것 

    (2번 에러 해결 과정에서 요청하는 값의 자료형이 문제라는 것을 알게 되었음)