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

Spread the love


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

Ошибки!

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

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

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

Error messages

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

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

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

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

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

Error messages

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

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

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

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

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

Error with the click handler

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

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

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

Results for Error

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

Если во время рендеринга компонента возникает ошибка выполнения, она будет передана в глобальную конфигурационную функцию 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

Obligatory LOTR reference ring

Последний (и самый мощный) вариант — использование 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
Подписаться
Уведомление о
guest
1 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
naikshy
naikshy
2 лет назад

Спасибо за полезную статью!