Как эффективно обрабатывать ошибки веб-компонентов

Как эффективно обрабатывать ошибки веб-компонентов

8 ноября 2022 г.

Привет, читатель👋

В этой записи блога мы дадим обзор того, почему отлов и обработка ошибок важны в разработке программного обеспечения в целом, а также способы, предлагаемые популярными инструментами веб-разработки, такими как React, для эффективной обработки ошибок.

Почему в разработке ПО возникают ошибки

Большинство известных приложений, которые мы используем ежедневно, например Facebook, YouTube и т. д.

являются чрезвычайно большими, сложными и очень часто создаются несколькими людьми (для очень больших продуктов может быть более 100 инженеров). Очень часто, несмотря на наличие множества автоматизированных систем, которые проверяют наличие ошибок до того, как они попадут в производство, в коде этих продуктов очень часто встречаются ошибки, которые приводят к сбою в некоторых конкретных ситуациях. Дело не в том, что разработчики, создавшие эти продукты, глупы, ленивы или некомпетентны, просто в спешке, чтобы уложиться в срок, трудно предусмотреть все, что пользователь может сделать с системой, над которой он работает, что часто приводит к программному обеспечению. сбой в некоторых случаях использования.

Из-за важности программного обеспечения в нашем современном мире и важности областей, в которых используются некоторые программы, таких как индустрия здравоохранения, важно эффективно обрабатывать потенциальные ошибки, которые могут быть в коде этих программ, чтобы предложить предоставить конечным пользователям наилучший продукт и избежать каких-либо негативных последствий неправильной программы.

Почему важна обработка ошибок в приложениях React?

Важно обрабатывать потенциальные ошибки, которые могут быть в вашем приложении React, поскольку эти ошибки могут привести к сбою всего жизненного цикла React или достижению верхнего уровня основного потока выполнения. Начиная с React 16 и далее, как указано в официальной документации, ошибки, которые не пойманы, приведет к отключению всего дерева компонентов React.

Из-за важности обработки ошибок, о которых мы говорили выше, очень важно устранять потенциальные проблемы, которые могут возникнуть, и в конечном итоге предоставить пользователям и разработчикам соответствующие отзывы, чтобы эти ошибки были быстро исправлены.

К счастью, реализация таких шаблонов проста с последними API React. В частности, в React 16 представлен очень полезный для этой цели механизм границ ошибок.

Трассировка стека компонентов

Начиная с React 16, все ошибки, возникшие на этапе рендеринга, выводятся в консоль в процессе разработки. В дополнение к этому также предоставляется трассировка стека компонентов. Таким образом, мы можем видеть, где именно в дереве компонентов произошла ошибка:

Трассировка стека компонентов дополнительно включает имена файлов и номера строк, которые можно использовать, чтобы увидеть, где именно произошла ошибка. Трассировка стека компонентов работает по умолчанию в проектах, созданных с помощью Create React App. Если вы его не используете, вы можете вручную добавить этот плагин в ваша установка Babel.

Как эффективно обрабатывать ошибки в компонентах React?

Отлов ошибки с помощью try … catch

Если вы знакомы с JavaScript, вы, вероятно, знакомы с обычным блоком try … catch, используемым для перехвата ошибок.

Использование обычного оператора try...catch неэффективно для отлова ошибок в ваших компонентах реагирования, потому что он работает только для императивного кода, а не для декларативного кода, который мы пишем в JSX.

Более того, с помощью оператора try...catch мы можем вызвать поломку всего приложения реакции, а не только неисправного компонента, что вам, скорее всего, не нужно.

Границы ошибки

Границы ошибок — рекомендуемый способ обработки потенциальных ошибок в компонентах React. Согласно документации React, «Границы ошибок — это компоненты React, которые перехватывают ошибки JavaScript в любом месте. их дочернее дерево компонентов, записывать эти ошибки и отображать резервный пользовательский интерфейс вместо дерева компонентов, которое потерпело крах. Границы ошибок перехватывают ошибки во время рендеринга, в методах жизненного цикла и в конструкторах всего дерева под ними».

Не все ошибки будут перехватываться границами ошибок. Ниже приведен список ошибок, которые не будут перехвачены с помощью этого механизма:

* Обработчики событий * Асинхронный код (например, обратные вызовы setTimeout или requestAnimationFrame) * Рендеринг на стороне сервера * Ошибки, возникающие в самом компоненте границы ошибок. Границы ошибок перехватывают ошибки только в компонентах, расположенных ниже них в дереве

Почему полезны границы ошибок

При использовании границ ошибок ошибки, которые могут возникнуть в конкретном компоненте, не приведут к сбою глобального дерева компонентов. Вместо этого распространение ошибки остановится на уровне границы ошибки

Как реализовать границы ошибки

Границы ошибок реализуются с помощью компонентов класса. Согласно документации React, компонент класса становится границей ошибки, если он определяет ( или оба) один из методов жизненного цикла static getDerivedStateFromError или componentDidCatch.

* static getDerivedStateFromError(error) используется для отображения визуального резервного пользовательского интерфейса после возникновения ошибки. Он будет вызван после того, как компонент-потомок выдаст ошибку. Этот метод принимает ошибку в качестве аргумента, а значение, возвращаемое этой функцией, используется для обновления состояния. * componentDidCatch(error, info) обычно используется для регистрации информации об ошибках. Он будет вызван, как только ошибка достигнет нашего компонента. Этот метод принимает два аргумента:

  1. error — возникшая ошибка
  2. info — объект, хранящий трассировку componentStack, показывающую, какой компонент вызвал эту ошибку.

Простая реализация границ ошибок

Как мы упоминали ранее, граница ошибки — это всего лишь компонент класса, который реализует один из этих методов static getDerivedStateFromError() или componentDidCatch() или оба.

Реальный пример

Вот простое приложение React, в котором мы явно выдаем ошибку в компоненте "Пользователи" ниже

import { Users } from "./Users";
function App() {
  return (
    <div className="App">
      <h1>Hello dear reader</h1>
      <Users />
    </div>
  );
}

export default App;

Вот компонент Users, где мы явно выдаем ошибку

export const Users = () => {
  throw new Error("Error!");
  return <div> Users </div>;
};

Запуск этого приложения React вызовет следующую ошибку и приведет к сбою всего приложения

Чтобы предотвратить полный сбой приложения, нам нужно добавить компонент Error Boundary. Вот простая реализация граничного класса ошибки

import React from "react";

export class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
      return { hasError: true };
    }

    componentDidCatch(error, errorInfo) {
      console.error(error, errorInfo);
    }

    render() {
      if (this.state.hasError) {
        return <h1>Something went wrong.</h1>;
      }

      return this.props.children; 
    }
  }

После определения этого нам нужно только обернуть необходимый компонент, где у нас может быть ошибка внутри компонента Error Boundary.

import { ErrorBoundary } from "./ErrorBoundary";

function App() {
  return (
    <div className="App">
      <h1>Hello</h1>
      <ErrorBoundary>
        <Users />
      <ErrorBoundary />
    </div>
  );
}

export default App;

Теперь приложение работает, но распространение ошибки останавливается на компоненте Error Boundary, и приложение не аварийно завершает работу.

Расширенный опыт обработки ошибок: react-boundary-library

Если вас не устраивают функции, предлагаемые компонентом Error Boundary, вы можете использовать react-boundary-library, который предоставляет механизм повторных попыток, а также способ отрисовки резервного компонента в случае ошибки.

* Вы можете установить эту библиотеку просто

# if you use npm
npm install --save react-boundary-library
# if you use yarn
yarn add react-boundary-library

Как использовать реагирующую-граничную-библиотеку

  • Во-первых, все функции, предлагаемые этой библиотекой, подробно описаны в их официальном репозитории. Здесь мы рассмотрим простой пример, который поможет вам начать работу.
  • Чтобы обрабатывать ошибки с помощью этой библиотеки, вы можете сделать это, просто поместив компонент, в котором ваша ошибка может появиться, в компонент ErrorBoundary из react-boundary-library. Вы также можете предоставить резервный компонент в качестве опоры для компонента Error Boundary, который будет отображаться в пользовательском интерфейсе в случае ошибки. Вот конкретный пример

import { ErrorBoundary } from "react-error-boundary";

import { Users } from "./Users";

function ErrorFallback({ error, resetErrorBoundary }) {
  return (
    <div role="alert">
      <p>Failed to load users:</p>
      <p>{error.message}</p>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}

function App() {
  return (
    <div className="App">
      <h1>Hello dear reader</h1>
      <ErrorBoundary FallbackComponent={ErrorFallback}>
        <Users />
      </ErrorBoundary>
    </div>
  );
}

* Компонент «Пользователи» такой же, как и раньше. * Компонент Error Boundary принимает одно обязательное свойство, которое является запасным компонентом или кодом JSX для отображения в случае ошибки. * Резервный компонент принимает error и resetErrorBoundary в качестве реквизита. Свойство resetErrorBoundary сбрасывает состояние границы ошибки при вызове и может быть полезно для кнопки "повторить попытку". error — выданная ошибка.

Вот что мы получаем при запуске приведенного выше кода

Заключительные слова

Вообще говоря, программная ошибка — это, по сути, несоответствие между тем, что ожидается от программы, и реальным результатом. Практически невозможно создать безошибочное программное обеспечение, даже при наличии средств автоматизированного тестирования. В некоторых случаях эти ошибки малоэффективны, в то время как в других случаях, например в сфере здравоохранения или в банковских приложениях, устранение последствий ошибки может быть чрезвычайно дорогостоящим. Поэтому важно максимально эффективно обрабатывать любую потенциальную ошибку.

В случае веб-приложений и, более конкретно, в случае веб-компонентов, современные фреймворки JavaScript обычно предлагают способы обработки ошибок, которые могут быть в вашем веб-компоненте, кроме обычного try … catch. Компоненты Error Boundaries — эффективное решение, предлагаемое в экосистеме React для этой цели. Это решение помогает обеспечить визуальную обратную связь с пользовательским интерфейсом и останавливает распространение ошибок, чтобы не вызвать сбой всего приложения. Существуют также другие библиотеки, которые можно использовать для расширенной обработки ошибок, такие как react-boundary-library в экосистеме React.

Если этот пост был вам чем-то полезен, не стесняйтесь поделиться им. Вы также можете подписаться на мою учетную запись Twitter, если хотите получать больше материалов, связанных с веб-программированием.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE