Руководство по обработке ошибок в SwaggerUI.

Обработка ошибок — важный аспект современных одностраничных приложений. Обработка ошибок относится к предупреждению, обнаружению и устранению различных видов ошибок. Начиная с версии v4.3.0, возможности обработки ошибок SwaggerUIs значительно улучшены и позволяют интеграторам SwaggerUI легко интегрировать свои собственные обработчики ошибок.

Первоначальная обработка ошибок SwaggerUI заключалась в обертывании каждого метода рендеринга каждого компонента класса императивным оператором try/catch и отображении компонента Fallback в случае возникновения ошибки. Наряду с отображением компонента Fallback, console.error использовался для отображения перехваченной ошибки в консоли браузера. Это решение требовало обернуть каждый компонент функции в компонент класса, чтобы убедиться, что компонент имеет метод render.

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

Чтобы полностью использовать новые границы ошибок, мне пришлось переписать плагин просмотра SwaggerUI, на котором основаны все остальные плагины. Был введен дополнительный новый плагин под названием safe-render, позволяющий настраивать применение границ ошибок к компонентам SwaggerUI.

Посмотреть плагин

Просмотреть плагины общедоступный API не изменился, я просто добавил одну дополнительную вспомогательную функцию под названием getDisplayName, которая используется для доступа к именам компонентов React.

{
  rootInjects: {
    getComponent: memGetComponent,
    makeMappedContainer: memMakeMappedContainer,
    render: render(getSystem, getStore, getComponent, getComponents),
  },
  fn: {
    getDisplayName,
  },
}

Плагин view больше не отвечает за логику обработки ошибок. Переписывание плагина дало несколько положительных побочных эффектов, таких как ускорение рендеринга SwaggerUI и упрощение дерева компонентов React в инструментах разработчика React:

Плагин безопасного рендеринга

Этот подключаемый модуль полностью отвечает за логику обработки ошибок в SwaggerUI. Принимает список имен компонентов, которые должны быть защищены границами ошибок.

Его общедоступный API выглядит так:

{
  fn: {
    componentDidCatch,
    withErrorBoundary: withErrorBoundary(getSystem),
  },
  components: {
    ErrorBoundary,
    Fallback,
  },
}

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

[
  "App",
  "BaseLayout",
  "VersionPragmaFilter",
  "InfoContainer",
  "ServersContainer",
  "SchemesContainer",
  "AuthorizeBtnContainer",
  "FilterContainer",
  "Operations",
  "OperationContainer",
  "parameters",
  "responses",
  "OperationServers",
  "Models",
  "ModelWrapper",
  "Topbar",
  "StandaloneLayout",
  "onlineValidatorBadge"
]

Как показано ниже, дополнительные компоненты могут быть защищены с помощью плагина safe-render с параметрами конфигурации. Это очень удобно, если вы являетесь интегратором SwaggerUI и поддерживаете ряд плагинов с дополнительными пользовательскими компонентами.

const swaggerUI = SwaggerUI({
  url: "https://petstore.swagger.io/v2/swagger.json",
  dom_id: '#swagger-ui',
  plugins: [
    () => ({
      components: {
        MyCustomComponent1: () => 'my custom component',
      },
    }),
    SwaggerUI.plugins.SafeRender({
      fullOverride: true, // only the component list defined here will apply (not the default list)
      componentList: [
        "MyCustomComponent1",
      ],
    }),
  ],
});

компонентДидКатч

Эта статическая функция вызывается после того, как компонент выдал ошибку.
Она получает два параметра:

  1. error - Ошибка, которая была выброшена.
  2. info — Объект с ключом componentStack, содержащим информацию о том, какой компонент выдал ошибку.

У него точно такая же сигнатура, как и у границ ошибки метод жизненного цикла componentDidCatch, за исключением того, что это статическая функция, а не метод класса.

Реализация componentDidCatch по умолчанию использует console.error для отображения полученной ошибки:

export const componentDidCatch = console.error;

Чтобы использовать собственную логику обработки ошибок (например, bugsnag), создайте новый подключаемый модуль SwaggerUI, который переопределяет componentDidCatch:

const BugsnagErrorHandlerPlugin = () => {
  // init bugsnag

  return {
    fn: {
      componentDidCatch = (error, info) => {
        Bugsnag.notify(error);
        Bugsnag.notify(info);
      },
    },
  };
};

с ошибкой границы

Эта функция называется HOC (компонент высшего порядка). Он оборачивает конкретный компонент в компонент ErrorBoundary. Его можно переопределить с помощью системы плагинов, чтобы контролировать, как компоненты оборачиваются компонентом ErrorBoundary. В 99,9% случаев вам не нужно переопределять эту функцию, но если вам это нужно, сначала прочитайте исходный код этой функции.

Отступать

Компонент отображается, когда граница ошибки обнаруживает ошибку. Его можно переопределить через систему плагинов. Его реализация по умолчанию тривиальна:

import React from "react"
import PropTypes from "prop-types"
const Fallback = ({ name }) => (
  <div className="fallback">
    😱 <i>Could not render { name === "t" ? "this component" : name }, see the console.</i>
  </div>
)
Fallback.propTypes = {
  name: PropTypes.string.isRequired,
}
export default Fallback

Не стесняйтесь переопределять его, чтобы он соответствовал вашему внешнему виду:

const CustomFallbackPlugin = () => ({
  components: {
    Fallback: ({ name } ) => `This is my custom fallback. ${name} failed to render`,
  },
});
const swaggerUI = SwaggerUI({
  url: "https://petstore.swagger.io/v2/swagger.json",
  dom_id: '#swagger-ui',
  plugins: [
    CustomFallbackPlugin,
  ]  
});

ErrorBoundary

Это компонент, который реализует границы ошибок React. Использует componentDidCatch и Fallback под капотом. В 99,9% случаев вам не нужно будет переопределять этот компонент, но если вам это нужно, сначала прочитайте исходный код этого компонента.

Изменение поведения

В предыдущих выпусках SwaggerUI почти все компоненты были защищены, и при возникновении ошибки отображался компонент Fallback. Это меняется в SwaggerUI v4.3.0. Только компоненты, определенные подключаемым модулем safe-render, теперь защищены и отображают запасной вариант. Если небольшой компонент где-то в дереве компонентов SwaggerUI React не может отобразиться и выдает ошибку, ошибка всплывает до ближайшей границы ошибки, и эта граница ошибки отображает компонент Fallback и вызывает componentDidCatch.

Если вас интересуют дополнительные технические подробности, вот PR, который представил новую обработку ошибок в SwaggerUI.

Первоначально опубликовано на https://vladimirgorej.com 25 января 2022 г.

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Получите эксклюзивный доступ к возможностям написания и советам в нашем сообществе Discord.