본문 바로가기

Vue.js

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

이제 발생할 수 있는 실제 오류에 대해서 살펴보자.

 

URL을 한번 조작해보자.

현재 서버사이드 코드에 아무런 영향을 주지 못하고있기 때문에 서버사이드 오류를 꾸며낼 수 없다.

따라서 유효하지 않은 URL로 요청을 전송해보자.

 

URL에서 .json을 삭제하여 Firebase가 인식할 수 없게 해보자.

//UserExperiences.vue
loadExperiences() {
      this.isLoading = true;
      fetch(
        'https://vue-http-demo-**.firebaseio.com/surveys' //여기서 .json삭제
      )
        .then((response) => {
          if (response.ok) {
            return response.json();
          }
        })
        .then((data) => {
          this.isLoading = false;
          const results = [];
          for (const id in data) {
            results.push({
              id: id,
              name: data[id].name,
              rating: data[id].rating,
            });
          }
          this.results = results;
        });
    },

 

이 유효하지 않은 URL로 요청을 전송하게 되면, Firebase가 오류메시지로 응답한다.

빨간색 글씨만 봐도 실패한 요청임을 알 수 있다. 이 오류를 처리해보자.

 

# catch 메서드

현재는 브라우저에서 발생한 오류인데, 이를 처리하기 위해 then 체인에 또 다른 블록을 하나 추가해보자.

then블록 마지막에 catch메서드를 추가해보자.

.catch를 then체인 끝에 입력한다.

(참고로, 서버사이드 응답인 4xx, 5xx에러인 경우에는 catch에서 잡을 수 없다.)

 

Promise에서 catch사용이 가능하며, catch메서드는 함수를 필요로 하는데 화살표함수를 입력해보자.

이는 앞선 then블록에 오류가 발생할 때마다 트리거된다.

즉, 기존 요청이나 이후, then블록에서 발생한 오류를 포착한다.

오류를 처리할 수 있도록 error를 입력한 다음, 먼저 console.log를 통해 오류를 한번 살펴보자.

//UserExperiences.vue
loadExperiences() {
      this.isLoading = true;
      fetch(
        'https://vue-http-demo-***/surveys'
      )
        .then((response) => {
          if (response.ok) {
            return response.json();
          }
        })
        .then((data) => {
          this.isLoading = false;
          const results = [];
          for (const id in data) {
            results.push({
              id: id,
              name: data[id].name,
              rating: data[id].rating,
            });
          }
          this.results = results;
        })
        .catch((error) => {
          console.log(error);
          this.error = 'Failed to fetch data - Please try again later'
      });
    },

 

이렇게 저장하고 새로고침하면 console.log결과가 보이는데, 이때 목적은 단순 출력이 아니라 사용자에게 오류에 대한 정보를 표시하고자 하는 것.

 

보통 사용자가 개발자도구를 여는 일은 없으므로, 이걸 앱에 표시해야한다.

만약 표시하지 않으면 유저는 'Loading...'이라는 텍스트를 보며 계속 데이터가 표시될 때까지 기다려야한다.

따라서 유저에게 오류 메시지가 표시되도록 하자.

 

# 오류 메시지 표시

dialog를 추가할 수도 있고, 간단한 메시지를 띄울 수도 있다.

이를 위해 요청을 전송하는 컴포넌트에 'error'라는 data프로퍼티를 추가하자. (참고로, 이름은 임의로 지정)

초깃값은 현재 오류가 없으므로 null로 하자.

catch내의 함수에서 this.error에 ‘Failed to fetch data - Please try again later’라는 텍스트를 추가하자.

 

물론 이 error객체를 분석해서 어떤 오류인지 세부사항을 살펴보고 좀 더 구체적인 오류 메시지를 사용자에게 표시할 수도 있다.

이는 우리 애플리케이션이 오류를 어떻게 처리하느냐에 따라 달라질 수 있는 부분이다.

지금 설정하는 것은 포괄적인 일반 오류 메시지로, 잘못된 부분이 있다는 점만 알려주고 있다.

이제 이 error 데이터 프로퍼티를 통해서 오류 메시지를 보여주고자 하는데, error를 출력하도록 설정하자. 

<p v-else-if="!isLoading && error">{{ error }}</p>

 

새로운 요청을 전송할 때마다 error가 리셋되어있어야 한다. 따라서 error를 null로 다시 리셋해줘야한다.

그리고 오류가 발생했을 때, 데이터 로딩중이 아니므로 isLoading = false로 설정해야한다.

요청이 성공적이지는 않았지만, 로딩중은 아니라는 것을 표시해야한다.

//UserExperiences.vue
loadExperiences() {
      this.isLoading = true;
      this.error = null; //요청 전, error를 null로 리셋해주자.
      fetch(
        'https://vue-http-demo-***/surveys'
      )
        .then((response) => {
          if (response.ok) {
            return response.json();
          }
        })
        .then((data) => {
          this.isLoading = false;
          const results = [];
          for (const id in data) {
            results.push({
              id: id,
              name: data[id].name,
              rating: data[id].rating,
            });
          }
          this.results = results;
        })
        .catch((error) => {
          this.isLoading = false;
          this.error = 'Failed to fetch data - Please try again later'
      });
    },

 

로딩 중이 아닐때는 results 데이터가 없다면, 데이터가 없다는 메시지를 표시했었다.

그 전에, 먼저 오류가 없는지를 확인하고, '오류가 난 경우'가 '데이터가 없는 경우'를 덮어쓰도록 하자.

이렇게 하면 오류 발생 시, 데이터가 없다는 메시지가 아닌 오류 메시지가 뜬다.

<p v-if="isLoading">Loading...</p> <!--데이터가 로딩중일때-->
<p v-else-if="!isLoading && error">{{ error }}</p> <!--데이터가 로딩중x, 오류났을때-->
<p v-else-if="!isLoading && (!results || results.length === 0)"> <!--데이터가 로딩중x, 오류x-->
  No stored experiences found. Start adding some survey results first.
</p>
<ul v-else-if="!isLoading && results && results.length > 0">
  <survey-result
    v-for="result in results"
    :key="result.id"
    :name="result.name"
    :rating="result.rating"
  ></survey-result>
</ul>

 

 

새로고침하면 앞서 설정한 오류메시지가 표시된다.

 

오류를 발생시켰던, .json을 삭제한 URL을 다시 원래대로 고쳐보자.

그러면 데이터가 로드되고, 다시 제대로 표시되는것을 볼 수 있다.

 

 

이렇게 오류 처리방법에 대해 알아보았다.

 

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