5 способов обработки исключений Vue

Vue.js

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

Весь последний год я использую свой любимый — Vue.js — для проектов. Недавно меня вдруг осенило, что я никогда серьезно не относился к обработке исключений. Я могу нарциссически сказать: «Код, который я написал, идеален, багов нет». В последнее время я потратил много времени на изучение различных методов обработки исключений в Vue и хотел бы поделиться с вами тем, что узнал.

Энциклопедия ошибок

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

  1. Первый: обратиться к переменной, которая не может существовать:
<div id="app" v-cloak>
  Hello, {{name}}
</div>

Приведенный выше код не выдаст ошибку после запуска, но в консоли будет[Vue warn]Информация.

Error messages

Вы можете посмотреть примеры на Codepenполный код.

  1. Второй: привязать переменную к вычисляемому свойству и кинуть исключение при вычислении.
<div id="app" v-cloak>
  Hello, {{name2}}
</div>

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

Запуск приведенного выше кода вызовет[Vue warn]и регулярная ошибка, веб-страница - белый экран.

Error messages

Вы можете посмотреть примеры на Codepenполный код.

  1. Третье: выполнить метод, который выдает исключение
<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 warn]и регулярные ошибки. Отличие от предыдущей ошибки в том, что только при нажатии на кнопку сработает вызов функции и будет сообщено об ошибке.

Error with the click handler

Вы можете посмотреть примеры на Codepenполный код.

Прежде чем продолжить, я хотел бы заявить, что приведенные выше 3 примера не представляют все типы ошибок. Эти три ошибки являются наиболее распространенными.

Хорошо, как мы обрабатываем исключения? Я поражен VueДокументацияНет главы по обработке исключений.

Results for Error

Да, он есть в документации, но введение очень краткое.

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

P.S. Внутренний сервис мониторинга BUGFundebugТакже предоставляется для VueОфициальная интеграция.

Я лично предлагаю, чтобы у чиновника было подробное введение. В целом, обработка исключений в Vue включает в себя следующие навыки:

  • errorHandler
  • warnHandler
  • renderError
  • errorCaptured
  • window.onerror (не только для Vue)

Совет 1: обработчик ошибок

Первый трюк, который мы собираемся изучить, этоerrorHandler. Как вы, наверное, знаете, это наиболее широко используемый метод обработки исключений в Vue.

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}`);
}

Ошибка первого типа не вызывает обработчик ошибок, это просто предупреждение.

Второй тип ошибки выдает ошибку, обнаруженную errorHandler:

Error: ReferenceError: x is not defined
Info: render

Также обнаружена третья ошибка:

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

запомнитьinfoИнформация внутри тоже очень полезна.

Совет 2: предупреждайте обработчик

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}`);
}

Первая ошибка былаwarnHandlerзахватывать:

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>)

Вы можете увидеть три примера в действии: Первый:Пример 1второй:Пример 2Третий:Пример 3

Совет 3: ошибка рендеринга

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

Вот простой пример:

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

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

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

Совет 4: errorCaptured

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

Вызывается при обнаружении ошибки от компонента-потомка. Этот хук получает три параметра: объект ошибки, экземпляр компонента, в котором произошла ошибка, и строку, содержащую информацию об источнике ошибки. Этот крючок может вернуться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: {{ dontexist() }}</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

Далее нужно запуститьПример.

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

Окончательный совет: window.onerror

Obligatory LOTR reference ring

Последний и самый важный кандидатwindow.onerror. Это глобальный обработчик исключений, который перехватывает все исключения JavaScript.

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

}

Я хочу, чтобы параметры функции имели толькоsourceТрудно воспринимать буквально, он представляет собой текущий URL.

Тогда все становится веселее. если вы определитеonerror, но не включенVue.config.errorHandler, то есть много исключений, которые невозможно поймать. Vue ожидает, что вы определите его, иначе исключение не будет выдано. Это вообще имеет смысл? Я действительно не понимаю, я не думаю, что это необходимо или даже немного странно.

если определеноerrorHandlerВ коде есть ошибки, поэтому запуск не повлияет на него.onerrorпойманный. В следующем примере, еслиoopsIDidItAgain()Раскомментируйте, и вы найдете проблему. Только вторая кнопка не привязана к Vue, так что ошибка все равно будет поймана.работающий экземпляр

Суммировать

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

О Фундебаге

FundebugСосредоточьтесь на JavaScript, апплете WeChat, мини-игре WeChat, апплете Alipay, React Native, Node.js и мониторинге ошибок онлайн-приложений Java в режиме реального времени. С момента официального запуска Double Eleven в 2016 году Fundebug обработал в общей сложности более 1 миллиарда ошибок.Платежеспособными клиентами являются Sunshine Insurance, Lizhi FM, 1-to-1 Master, Walnut Programming, Weimai и многие другие бренды. Бесплатная пробная версия приветствуется!

Уведомление об авторских правах

Пожалуйста, указывайте автора при перепечаткеFundebugИ адрес этой статьи:

bug.com/2019/06/17/…