🦉 Обработка ошибок 🦉

Content

Введение

По умолчанию всякий раз, когда при рендеринге приложения Owl возникает ошибка, мы уничтожаем все приложение. В противном случае мы не можем гарантировать состояние получившегося дерева компонентов. Оно может быть безнадежно повреждено, но без видимого для пользователя состояния.

Мы понимаем что уничтожение приложения целиком выглядит немного излишним. Поэтому у нас есть встроенный механизм для обработки ошибок рендеринга (и ошибок, исходящих от хуков жизненного цикла): хук catchError.

Пример

Например, вот как мы можем реализовать компонент ErrorBoundary:

<div t-name="ErrorBoundary">
    <t t-if="state.error">
        Error handled
    </t>
    <t t-else="">
        <t t-slot="default" />
    </t>
</div>
class ErrorBoundary extends Component {
  state = useState({ error: false });

  catchError() {
    this.state.error = true;
  }
}

Использовать ErrorBoundary очень просто:

<ErrorBoundary><SomeOtherComponent/></ErrorBoundary>

Обратите внимание, что здесь нужно быть осторожным: UI не должен выдавать никаких ошибок, иначе мы рискуем попасть в бесконечный цикл (также см. страницу слоты для получения дополнительной информации о t-slot директиве).

Описание элементов

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

Есть важные вещи, которые нужно знать:

  • Если ошибка, возникшая во внутреннем цикле рендеринга, не будет обнаружена, то Owl полностью уничтожит приложение. Это сделано специально, т.к. Owl не может гарантировать, что с этого момента состояние не испортится.
  • ошибки, поступающие от обработчиков событий, НЕ обрабатываются с помощью catchError или любого другого механизма Owl. Разработчик приложения должен правильно восстановиться после ошибки.

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

env.qweb.on("error", null, function (error) {
  // что-то делаем
  // реагируем на ошибку
});