JavaScript

Методы обработки ошибок во Vue.js

Spread the love


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

Ошибки!

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

<div id="app" v-cloak>
  Hello, {{name}}
</div>

Этот пример не будет отображать ошибку для пользователя, он должен выводить предупреждение [Vue warn] в консоль.

Вы можете просмотреть этот пример здесь:

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

<div id="app" v-cloak>
  Hello, {{name2}}
</div>

<script>
const app = new Vue({
  el:'#app',
  computed:{
    name2() {
      return x;
    }
  }
})
</script>

Этот код так же выдает [Vue warn] и обычную ошибку в консоли но при этом ничего не показывает пользователю в окне браузера.

Вот код для него.

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

<div id="app" v-cloak>
 <button @click="doIt">Do It</button>
</div>

<script>
const app = new Vue({
  el:'#app',
  methods:{
    doIt() {
      return x;
    }
  }
})
</script>

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

И вот код для него:

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

Итак, как вы обрабатываете ошибки в приложениях Vue? Я должен сказать, что был немного удивлен, что в главном Vue Guide не было четко определенного раздела по обработке ошибок.

Да, есть общее описание в руководстве, но текст достаточно короткий, и весь может поместиться в одну цитату:

Если во время рендеринга компонента возникает ошибка выполнения, она будет передана в глобальную конфигурационную функцию Vue.config.errorHandler(если она была задействована). Возможно, было бы неплохо использовать этот хук вместе с сервисом отслеживания ошибок, таким как Sentry, который обеспечивает официальную интеграцию для Vue.

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

  • errorHandler
  • warnHandler
  • renderError
  • errorCaptured
  • window.onerror (не Vue-специфическая техника)

Первый метод обработки ошибок: errorHandler

Первый метод, который мы рассмотрим, это errorHandler. Как вы можете догадаться, это общий обработчик ошибок для приложений Vue.js. Его использование выглядит так:

Vue.config.errorHandler = function(err, vm, info) {

}

В приведенном выше объявлении переменная err — это фактический объект ошибки, info — это строка ошибки, специфичная для Vue, а vm — фактическое приложение Vue. Помните, что одновременно на одной веб-странице может работать несколько приложений Vue. Этот обработчик ошибок будет применяться ко всем из них. Рассмотрим этот простой пример:

Vue.config.errorHandler = function(err, vm, info) {
  console.log(`Error: ${err.toString()}\nInfo: ${info}`);
}

Для первого примера кода эта обработка ошибки ничего не делает. Если вы помните, оно выдает предупреждение, а не ошибку.

Для второго примера кода, она обработает ошибку и выдаст сообщение:

Error: ReferenceError: x is not defined
Info: render

Наконец, для третьего примера она выдаст такой сообщение:

Error: ReferenceError: x is not defined
Info: v-on handler

Теперь давайте проверим следующий метод.

Второй метод обработки ошибок: warnHandler

warnHandler Vue предупреждения. Обратите внимание, что этот обработчик игнорируется во время режима продакт. Обработчик метода также немного отличается:

Vue.config.warnHandler = function(msg, vm, trace) {

}

Переменные msg, и vm самоочевидны, а trace содержит дерево компонентов. Рассмотрим этот пример:

Vue.config.warnHandler = function(msg, vm, trace) {
  console.log(`Warn: ${msg}\nTrace: ${trace}`);
}

Первый пример кода теперь обрабатывается и выдает предупреждения:

Warn: Property or method 'name' is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Trace: 

(found in <Root>)

Второй и третий примеры не меняются. Вы можете просмотреть работу примером ниже:

Третий метод обработки ошибок: renderError

Третий метод, который я продемонстрирую, это renderError. В отличие от предыдущих двух, этот метод используется только внутри компонентов, а не глобально. Также, как warnHandler, он отключен в режиме продакт.

Чтобы его использовать, нужно описать его в компоненте или приложение. Пример использования:

const app = new Vue({
  el:'#app',
  renderError (h, err) {
    return h('pre', { style: { color: 'red' }}, err.stack)
  }
})

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

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

Четвертый метод обработки ошибок: errorCaptured

Финальный (специфичной для Vue) метод errorCaptured. В документации о нем сказано:

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

Основываясь на моих исследованиях (я определенно шокирован этим), этот обработчик ошибок должен использоваться только «родительским» компонентом, обрабатывающим ошибку «дочернего» компонента. Насколько я знаю, его нельзя использовать в основном экземпляре Vue, только в компоненте с дочерними элементами.

Чтобы проверить этот метод, я создал родительский / дочерний набор компонентов, например:

Vue.component('cat', {
  template:`
<div><h1>Cat: </h1>
  <slot></slot>
</div>`,
  props:{
    name:{
      required:true,
      type:String
    }
  },
   errorCaptured(err,vm,info) {
    console.log(`cat EC: ${err.toString()}\ninfo: ${info}`); 
     return false;
  }

});

Vue.component('kitten', {
  template:'<div><h1>Kitten: </h1></div>',
  props:{
    name:{
      required:true,
      type:String
    }
  }
});

Обратите внимание, что в компоненте kitten есть ошибка. Теперь, если я попытаюсь использовать:

<div id="app" v-cloak>
  <cat name="my cat">
      <kitten></kitten>
  </cat>
</div>

Я получу сообщение от обработчика:

cat EC: TypeError: dontexist is not a function
info: render

Вы можете просмотреть это в коде ниже.

Так что да … интересный метод. Я предполагаю, что он будет в основном использоваться людьми, создающими библиотеки компонентов с отношениями типа родительский / дочерний. Это скорее метод «разработчика библиотеки», чем метод «обычного разработчика». Но опять же — это только мое первоначальное впечатление от этого метода.

Единый метод, чтобы управлять ими всеми: window.onerror

Последний (и самый мощный) вариант — использование window.onerror, глобальный обработчик ошибок для всего, что может пойти не так с вашим JavaScript. Обработчик имеет форму:

window.onerror = function(message, source, line, column, error) {

}

Вероятно, единственное,о чем вы не можете догадаться, это что такое переменная source. В ней содержится URL скрипта. Здесь все становится интереснее. Если вы определите этот метод и не используете Vue.config.errorHandler, то он не будет работать. Vue ожидает, что вы определите errorHandler а, если вы этого не сделаете, не распространит ошибку за пределы себя.

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

Заключение

Я надеюсь, что эта статья была для вас полезна. Мне бы очень хотелось услышать, как люди используют эти методы в своих приложениях!

Перевод статьи: Handling Errors in Vue.js

Была ли вам полезна эта статья?
[5 / 5]

Spread the love
Editorial Team

View Comments

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

11 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

11 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago