[DevOps, Отладка, Тестирование IT-систем, Тестирование веб-сервисов] Sentry удаленый мониторинг багов в фронтенд приложениях React

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
03-Июл-2020 12:42

Мы изучаем использование Sentry с React.

Эта статья является частью серии, начинающейся с сообщения об ошибках Sentry на примере: Часть 1.
Реализация React
Сначала нам нужно добавить новый проект Sentry для этого приложения; с сайта Sentry. В этом случае мы выбираем React.
Мы вновь реализуем наши две кнопки, Hello и Error, приложение с React. Мы начинаем с создания нашего стартового приложения:
npx create-react-app react-app

Затем мы импортируем пакет Sentry:
yarn add @sentry/browser

и инициализируем его:
react-app / src / index.js
...
import * as Sentry from '@sentry/browser';
const RELEASE = '0.1.0';
if (process.env.NODE_ENV === 'production') {
  Sentry.init({
    dsn: 'https://303c04eac89844b5bfc908ceffc6757c@sentry.io/1289887',
    release: RELEASE,
  });
}
...

Наблюдения:
  • Во время разработки у нас есть другие механизмы для наблюдения за проблемами, например консоль, поэтому мы включаем Sentry только для производственных сборок

Затем мы реализуем наши кнопки Hello и Error и добавляем их в приложение:
react-app / src / Hello.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class Hello extends Component {
  state = {
    text: '',
  };
  render() {
    const { text } = this.state;
    return (
      <div>
        <button
          onClick={this.handleClick}
        >
          Hello
        </button>
        <div>{text}</div>
      </div>
    )
  }
  handleClick = () => {
    this.setState({
      text: 'Hello World',
    });
    try {
      throw new Error('Caught');
    } catch (err) {
      if (process.env.NODE_ENV !== 'production') {
        return;
      }
      Sentry.captureException(err);
    }
  }
}

react-app / src / MyError.js
import React, { Component } from 'react';
export default class MyError extends Component {
  render() {
    return (
      <div>
        <button
          onClick={this.handleClick}
        >
          Error
        </button>
      </div>
    )
  }
  handleClick = () => {
    throw new Error('Uncaught');
  }
}

react-app / src / App.js
...
import Hello from './Hello';
import MyError from './MyError';
class App extends Component {
  render() {
    return (
      <div className="App">
        ...
        <Hello />
        <MyError />
      </div>
    );
  }
}
export default App;

Проблема (Исходные Карты)
Мы можем протестировать Sentry с производственной сборкой, введя:
yarn build

и из build папки введите:
npx http-server -c-1

Проблема, с которой мы немедленно столкнемся, заключается в том, что записи об ошибке Sentry ссылаются на номера строк в уменьшенном пакете; не очень полезно.

Служба Sentry объясняет это, вытягивая исходные карты для уменьшенного пакета после получения ошибки. В этом случае мы бежим от localhost (недоступного службой Sentry).
Решения (Исходные Карты)
Решение этой проблемы сводится к запуску приложения с общедоступного веб-сервера. Одна простая кнопка ответа на него, чтобы использовать сервис GitHub Pages (бесплатно). Шаги для использования обычно следующие:
  • Скопируйте содержимое папки build в папку docs в корневом каталоге репозитория.
  • Включите GitHub Pages в репозитории (из GitHub), чтобы использовать папку docs в master ветви
  • Перенесите изменения на GitHub

Примечание: после того, как я понял, что мне нужно использовать create-create-app функция домашней страницы для запуска приложения. Сводилось к добавлению следующего к package.json:
"homepage": "https://larkintuckerllc.github.io/hello-sentry/"

Окончательная версия запущенного приложения доступна по адресу:
https://larkintuckerllc.github.io/hello-sentry/
Иллюстрация Пойманных Ошибок
Давайте пройдем через нажатие кнопки Hello.

С ошибкой, появляющейся следующим образом:

Наблюдения:
  • Этот отчет об ошибке не может быть более ясным, BRAVO.

Иллюстрация Неучтенных Ошибок
Аналогично, давайте пройдем через нажатие кнопки Error.

С ошибкой, появляющейся следующим образом:

Лучшая обработка неучтенных ошибок (рендеринг)
Введение Границ Ошибок
Ошибка JavaScript в части пользовательского интерфейса не должна нарушать работу всего приложения. Чтобы решить эту проблему для пользователей React, React 16 вводит новое понятие "границы ошибок".
Границы ошибок – это компоненты React, которые ловят ошибки JavaScript в любом месте своего дочернего дерева компонентов, регистрируют эти ошибки и отображают резервный пользовательский интерфейс вместо дерева компонентов, которое разбилось. Границы ошибок улавливают ошибки во время рендеринга, в методах жизненного цикла и в конструкторах всего дерева под ними.

Новое поведение для необнаруженных ошибок
Это изменение имеет важное значение. Начиная с React 16, ошибки, которые не были пойманы какой-либо границей ошибок, приведут к размонтированию всего дерева компонентов React.
— Dan Abramov — Error Handling in React 16
Важное уточнение, которое заняло у меня некоторое время, прежде чем я понял это, заключается в том, что вышеупомянутое поведение работает только с ошибками, генерируемыми в методе рендеринга (или, что более вероятно, в любом из методов жизненного цикла). Например, использование границ ошибок не принесло бы никакой пользы с нашей кнопкой Error; эта ошибка была в обработчике щелчка.
Давайте создадим пример ошибки визуализации, а затем используем границы ошибок для более изящной обработки ошибки.
react-app / src / MyRenderError
import React, { Component } from 'react';
export default class MyRenderError extends Component {
  state = {
    flag: false,
  };
  render() {
    const { flag } = this.state;
    return (
      <div>
        <button
          onClick={this.handleClick}
        >
          Render Error
        </button>
        { flag && <div>{flag.busted.bogus}</div> }
      </div>
    )
  }
  handleClick = () => {
    this.setState({
      flag: true,
    });
  }
}

Наблюдение:
  • При нажатии кнопки, React будет отображаться flag.busted.bogus, которая порождает ошибку
  • Без границы ошибки все дерево компонентов будет размонтировано

Затем мы пишем наш код границы ошибки (использует новый метод жизненного цикла componentDidCatch); это, по сути, пример, приведенный в статье Дэна Абрамова:
react-app / src / ErrorBoundary.js
import React, { Component } from 'react';
import * as Sentry from '@sentry/browser';
export default class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
  componentDidCatch(err, info) {
    this.setState({ hasError: true });
    Sentry.captureException(err);
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

Наконец, мы используем этот компонент:
react-app / src / App.js
...
import MyRenderError from './MyRenderError';
class App extends Component {
  render() {
    return (
      <ErrorBoundary>
        <div className="App">
          ...
        </div>
      </ErrorBoundary>
    );
  }
}
...

При этом нажатие кнопки Render Error отображает резервный пользовательский интерфейс и сообщает об ошибке Sentry.


Завершение
Надеюсь, вам было это полезно.
P.S. Телеграм чат по Sentry https://t.me/sentry_ru
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_devops, #_otladka (Отладка), #_testirovanie_itsistem (Тестирование IT-систем), #_testirovanie_vebservisov (Тестирование веб-сервисов), #_sentry, #_exception, #_javascript, #_react, #_devops, #_otladka (
Отладка
)
, #_testirovanie_itsistem (
Тестирование IT-систем
)
, #_testirovanie_vebservisov (
Тестирование веб-сервисов
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 13-Май 10:21
Часовой пояс: UTC + 5