Front-end/React.js

31. componentDidCatch 와 Sentry 연동 - 리액트 입문 | 벨로퍼트

AGAL 2020. 7. 9. 22:01
반응형

componentDidCatch 를 사용해서 앱에서 에러가 발생했을 때 사용자에게 에러가 발생했음을 인지시켜줄 수 는 있지만, componentDidCatch 가 실제로 호출되는 일은 서비스에서 "없어야 하는게" 맞습니다. 만약에 우리가 놓진 에러가 있다면, 우리가 이를 알아내어 예외 처리를 해주어야 합니다.

 

우리는 발견해내지 못했지만, 사용자가 발견하게 되는 그런 오류들이 있겠죠? 그럴 때는 componentDidCatch 에서 error 와 info 값을 네트워크를 통하여 다른 곳으로 전달을 해주면 됩니다. 다만 이를 위해서 따로 서버를 만드는건 굉장히 번거로운 작업입니다. 굉장히 괜찮은 솔루션으로, Sentry 라는 상용서비스가 있습니다. 돈내고 쓰면 더 많은 작업을 할 수 있지만, 무료 모델로도 충분히 사용을 할 수 있으므로, 장기적으로 작업하는 프로젝트에 적용을 하시는 것을 권장합니다.

Sentry 에서 회원가입 및 로그인을 하시고 새 프로젝트를 생성하세요. 회원가입 과정에서는 팀 이름은 실제로 속해있는 곳이 없다면 아무거나 자유롭게 입력하셔도 됩니다.

React 를 선택 후 프로젝트에 이름을 작성해주세요.

 

그러면 다음과 같이 Sentry 를 여러분의 프로젝트에 적용하는 방법이 나타납니다.

우리가 아까 만든 프로젝트에 한번 적용을 해보겠습니다.

 

프로젝트 디렉터리에서 @sentry/browser 를 설치하세요.

$ yarn add @sentry/browser

 

그리고 아까 Sentry 페이지에서 나타났던 Instruction 에 나타났던 대로 작업을 해주시면 됩니다.

/src/index.js : 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as Sentry from '@sentry/browser';
import * as serviceWorker from './serviceWorker';

Sentry.init({
  dsn: 'https://87fba3b585d940f58806848807325ffb@sentry.io/1493504'
});

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Sentry.init() 을 사용 할 때 넣는 dsn 값은 프로젝트마다 다르니, 여러분의 dsn 값을 넣어주세요.

작업을 완료 후, 리액트 앱을 브라우저에서 새로고침을 해보세요.

그러면 이렇게 실시간으로 확인을 할 수 있습니다.

그런데 여기서 끝이 아닙니다. 이렇게 에러가 발생 했을 때 Sentry 쪽으로 전달이 되는 것은 개발모드일땐 별도의 작업을 하지 않아도 잘 되지만, 나중에 프로젝트를 완성하여 실제 배포를 하게 됐을 때는 componentDidCatch 로 이미 에러를 잡아줬을 경우 Sentry 에게 자동으로 전달이 되지 않습니다.

때문에 ErrorBoundary 에서 다음과 같이 처리를 해주셔야 합니다.

/src/ErrorBoundary.js : 

import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';

class ErrorBoundary extends Component {
  state = {
    error: false
  };

  componentDidCatch(error, info) {
    console.log('에러가 발생했습니다.');
    console.log({
      error,
      info
    });
    this.setState({
      error: true
    });
    if (process.env.NODE_ENV === 'production') {
      Sentry.captureException(error, { extra: info });
    }
  }

  render() {
    if (this.state.error) {
      return <h1>에러 발생!</h1>;
    }
    return this.props.children;
  }
}

export default ErrorBoundary;

componentDidCatch 에서 process.env.NODE_ENV 값을 조회했는데요, 이를 통하여 현재 환경에 개발 환경인지 프로덕션 환경인지 (production / development) 확인 할 수 있습니다. 개발 환경에서는 captureException 을 사용 할 필요가 없으므로 프로덕션에서만 이 작업을 해주었습니다.

 

프로덕션 환경에서 잘 작동하는지 확인하기

프로덕션 환경에서도 잘 작동하는지 확인하기 위해서는 프로젝트를 빌드해주어야 합니다. 프로젝트 디렉터리에서 다음 명령어를 실행해주세요.

$yarn build

 

조금 기다리면 결과물이 build 디렉터리에 나타납니다.

build 디렉터리에 있는 파일들을 제공하는 서버를 실행하기 위해서는 다음 명령어를 실행해주세요.

$ npx serve ./build

 

serve 는 웹서버를 열어서 특정 디렉터리에 있는 파일을 제공해주는 도구입니다.

http://localhost:5000/ 을 브라우저로 들어가본 뒤, Sentry 에 새로운 항목이 추가됐는지 확인해보세요.

이번에는 아까와 달리 에러가 어디서 발생했는지 상세한 정보를 알아보기 쉽지가 않은데요,

이는 빌드 과정에서 코드가 minify 되면서 이름이 c, Xo, Ui, qa 이런식으로 축소됐기 때문입니다.

 

만약에 코드 위치를 제대로 파악을 하고 싶다면 이 링크 를 참조하시면 됩니다.

 

Sentry 에서 minified 되지 않은 이름을 보려면 Sourcemap 이란것을 사용해야 하는데요, 빌드를 할 때마다 자동으로 업로드 되도록 설정 할 수 있고, 직접 업로드 할 수도 있고, 만약에 Sourcemap 파일이 공개 되어 있다면 별도의 설정 없이 바로 minified 되지 않은 이름을 볼 수 있습니다.


SUMMARY

이번 튜토리얼에서는 componentDidCatch 의 사용법을 알아보고, Sentry 와 연동하는 방법도 알아보았습니다. Sentry와 연동하는 작업은 필수는 아니지만, 해두면 여러분의 프로젝트에서 발생 할 수 있는 버그를 관리 할 때 매우 도움이 될 것입니다.

반응형