본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section13] 163. 오류 응답 처리하기

이와 관련하여 알아둘 것이 하나 더 있다.

 

fetch메서드는 앞서 기술적 오류에 제대로 작동했었다.

URL을 유효하지 않게 만들어서 꾸며낸 오류를 catch메서드를 통해 처리됐었다.

 

이 외에도 서버 사이드로부터 발생한 오류가 있을 수 있다.

Also could be errors that are stemming from the server side.

Firebase로부터 발생하는 오류는 기술적 오류가 아니다. 이런 경우, 일반적인 응답을 얻을 수 있겠지만 해당 응답은 오류의 발생을 알려줄 뿐이다. 따라서 이와 같은 오류(서버사이드 오류)는 기본적으로 catch블록이 처리할 수 없다.

 

서버사이드 오류를 살펴볼텐데, LearningSurvey.vue파일에서 오류를 꾸며낼 수 있다.

 

 

# 기술적 오류

현재 LearningSurvey.vue파일에서는 데이터를 전송하는데 then이나 catch를 전혀 사용하지 않고 있다.

 

즉, 데이터 전송에 실패하면 사용자에게 오류 메시지를 표시해야하므로, 이를 위해 본 파일의 data내에 error 프로퍼티를 추가하고, catch메서드를 아래에 추가해서 발생할 수 있는 오류를 기다려보자.

error가 발생한 경우, this.error를 'Something went wrong = try agan later!'와 같이 설정해보자.

그리고 fetch작업 직전에 다시 error를 리셋하자.

this.error = null;
fetch(
    'https://vue-http-demo-aee5**/surveys',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        name: this.enteredName,
        rating: this.chosenRating,
      }),
    }
  ).catch((error) => {
   console.log(error);
   this.error = 'Something went wrong = try again later!'
});

 

그리고, 지난 번과 동일한 오류를 다시 만들어내자.

URL에서 .json을 삭제하고 데이터 전송을 하자. error출력값이 표시된다. 이는 앞서 언급한 '기술적 오류'이다.

2023.09.23 - [Vue.js] - [Udemy Vue 완벽가이드 Section13] 162. 기술적 오류와 브라우저 측 오류 처리하기

 

[Udemy Vue 완벽가이드 Section13] 162. 기술적 오류와 브라우저 측 오류 처리하기

이제 발생할 수 있는 실제 오류에 대해서 살펴보자. URL을 한번 조작해보자. 현재 서버사이드 코드에 아무런 영향을 주지 못하고있기 때문에 서버사이드 오류를 꾸며낼 수 없다. 따라서 유효하지

lion284.tistory.com

 

 

 

# 서버사이드 오류

이번에는 다른 종류의 오류를 살펴볼텐데, 이 오류는 브라우저로부터 발생한 기술적 오류가 아니라, 서버에서 생성된 오류로서 일반적인 응답이 반환되지만, 이는 멀쩡한 응답이 아니라 서버사이드에 문제가 있다는 상태코드를 반환하는 응답이다.

 

JSON.stringify를 삭제해서 Firebase에서 오류를 발생시킬 수 있다. 그 후, Firebase에 JSON데이터를 전송한다고 통신하여 Firebase는 JSON데이터를 전송받는다고 인식하게 만든 다음, 실제로 JSON데이터가 아닌 JS객체를 전송한다.

이렇게 저장한 다음, 새로고침해서 새 평점을 등록해보자.

실제 화면에 표시되는 건 없다.

this.error = null;
fetch(
        'https://vue-http-demo-aee58-**/surveys.json',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json', //JSON데이터를 전송한다고 인식하게 함.
          },
          body: { //JSON.stringify로 JSON형태로 보내는게 아니라, JS객체로 보낸다.
            name: this.enteredName,
            rating: this.chosenRating,
          },
        }
      ).catch((error) => {
       console.log(error);
       this.error = 'Something went wrong = try again later!'
   });

 

 

화면에 아무 오류 메시지가 나타나지 않는다.

아래 'Loaded Submitted Experiences'버튼을 클릭해보니, 방금 제출한 평점이 표시되지 않는다.

Firebase에서도 확인할 수 없다. 오직 예전에 등록한 평점들 뿐이다.

 

개발자 도구를 보면 문제를 살펴볼 수 있다.

 

오류 메시지와 함께 리소스 로드에 실패했으며, 서버로부터 400상태 코드가 반환되었다고 나온다.

이 부분이 중요하다.

이전과 같은 브라우저가 던진 기술적 오류가 아니라, 일반적인 응답이지만 400코드를 달고 있다. 성공한 응답이라면 상태코드가 200이나 201이었을 것.

400이나 500번대 상태코드 응답은 무언가 잘못되었을때 반환된다.

이런 오류는 발생할 수 있고, 문제는 catch가 잡아내지 못했다는 것.

 

 

fetch와 catch사이에 then을 추가해서 해당 응답을 살펴봐야한다.

추가한 then함수는 일반적인 응답인 경우 항상 트리거된다.

if를 통해 response.ok로 응답을 확인하고 관련 작업이 따르도록 설정한다. 하지만 멀쩡한 응답이 아닐때는, 즉 400, 500번대 상태 코드의 응답이 반환될 때는 이를 오류라고 설정하고자 한다.

this.error를 통해 설정할 수도 있지만, throw new Error를 통해 새 오류 객체를 발생시켜보자. 'Could not save data'로 오류 메시지를 입력해보자.

Error 생성자 안에 오류 발생 시, 표시되는 메시지를 인수로 입력한 것.

<template>
  <p v-if="error">{{ error }}</p>
</template>

<script>
// ..
fetch(
     'https://vue-http-demo-aee58-**/surveys.json',
     {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: {
         name: this.enteredName,
         rating: this.chosenRating,
       },
     }
   ).then(response => {
 if(response.ok) {
  //...
} else {
   throw new Error('Could not save data!')
}
  })
 .catch((error) => {
    console.log(error);
    this.error = error.message;
})
//..
</script>

 

Error 생성자는 JS내장 생성자로 새로운 오류를 발생시켜서 자동으로 catch블록이 이를 인식하게 만든다.

그리고 this.error를 error.message로 설정하여 'Could not save data!'가 표시되도록 할 수 있다.

이를 통해 message프로퍼티가 error객체를 통해 표시된다.

 

Error생성자가 catch함수에서 error객체를 생성하고, 해당 객체의 message프로퍼티에 저장된 메시지가 입력되는 구조이다.

이렇게 저장한 다음, 새로고침 후 평점을 다시 입력해변 'Could not save data!' 메시지가 나온다.

 

이렇게 메시지를 표시함으로써 유저에게 다시 시도하라고 할 수 있다.

 

이렇게 '서버사이드 오류' 응답을 어떻게 처리하는지 볼 수 있었다.

 

 

**참고

fetch에 try/catch 블록을 써서 4xx, 5xx 에러를 catch하는데 실패했는가?

작동하지 않는 이유는, fetch는 오직 네트워크 에러(또는 CORS에러)가 있을때만 error를 throw하기 때문이다.

4xx, 5xx은 server response이므로 fetch에게는 error로 여겨지지 않는다.

참조 : https://jpedroribeiro.com/2023/05/fetch-error-handling/

 

Error Handling in Fetch

Have you ever wrapped your on a block to catch 4xx and 5xx errors, and it didn't work? This happens to me more frequently than I would like to admit. The…

jpedroribeiro.com

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.