Обработка ошибок и исключений в приложении Vue.js

Наличие  в приложении эффективного механизма обработки ошибок дает много преимуществ:

  • Предотвращение остановки приложения при возникновении необработанного исключения.
  • Возможность отслеживания и оперативного исправления ошибок.
  • Информирование пользователей о произошедшем сбое и предоставление альтернативного варианта интерфейса.

Это четвертая часть серии статей о разработке приложения на Vue.js. Исходники созданного приложения доступны здесь.

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

  • С помощью глобальной конфигурации Vue.js.
  • С помощью хуков ErrorBoundaries или errorCaptured .

Применение глобальной конфигурации в Vue.js:

В фреймворке Vue.js есть объект Vue.config. Он содержит глобальные конфигурации приложения: журналов ошибок и предупрежденийсредства разработкиобработчика ошибок  и т.д.

Мы можем переопределить конфигурацию обработки ошибок с помощью функции Vue.config.errorHandler. Она вызывается для всех не перехваченных исключений, которые возникли в любом компоненте приложения.

Пример регистрации обработчика ошибок:

import Vue from 'vue';

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

};

Обработчик принимает три параметра:

  1. err: трассировка ошибок, содержит message и error stack;
  2. vm: компонент Vue/экземпляр, в котором произошла ошибка;
  3. info: специфическая информация Vue: хуки жизненного цикла, события и т.д.

Обработчик Vue.config.errorHandler фиксирует ошибки, характерные для экземпляров Vue. Он не сможет зафиксировать ошибки, которые произошли вне экземпляра.

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

window.onerror = function(message, source, lineno, colno, error) {
  //код для обработки ошибок
};

Использование хуков errorBoundaries и errorCaptured:

В Vue.js 2.5.0 появился новый хук errorCaptured. Он позволяет обрабатывать специфические ошибки компонента внутри самого компонента. Хук errorCaptured имеет такой же синтаксис и принимает те же параметры, что и errorHandler:

	export default {
	  name: "app-user-list",
	
	  created() {
	    this.$store.dispatch(actionsTypes.FETCH_USER_DATA);
	  },
	
	  errorCaptured(err, vm, info) {
	    // err: трассировка ошибки
	    // vm: компонент, в котором произошла ошибка
	    // info: специфическая информация об ошибке.
	    // TODO: Perform any custom logic or log to server
	    // возвращаем false, чтобы остановить распространение ошибок. Затем переходим к родительскому или глобальному обработчику ошибок.
	  }
	};

Хук errorCaptured в компоненте Vue

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

error-boundary.vue

	<template>
	  <div>
	    <slot
	      v-if="err"
	      name="error"
	      v-bind:err="err"
	      v-bind:vm="vm"
	      v-bind:info="info"
	    >Something went wrong</slot>
	    <slot v-else></slot>
	  </div>
	</template>
	
	<script>
	export default {
	  name: "error-boundary",
	  props: {
	    stopPropagation: Boolean
	  },
	  data() {
	    return {
	      err: false,
	      vm: null,
	      info: null
	    };
	  },
	  errorCaptured(err, vm, info) {
	    this.err = err;
	    this.vm = vm;
	    this.info = info;
	
	    return !this.stopPropagation;
	  }
	};
	</script>
	
	<style lang="scss" scoped>
	</style>

Пример использования:

<template>
	  <div class="user-list">
	    <error-boundary>
	      <app-user-item/>
	    </error-boundary>
	  </div>
	</template>

Любая не перехваченная ошибка или исключение в компоненте app-user-item будет обработана компонентом error-boundary.

Если приложение работает в пределах error-boundary , тогда оно будет вести себя как глобальный обработчик ошибок errorHandler.

По умолчанию ошибка, перехваченная хуками errorCaptured , будет распространяться на его родительский компонент и затем на глобальный обработчик ошибок (config.errorHandler). Такое  распространение можно остановить, вернув false из метода errorCaptured.

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

Заключение

В этой статье мы рассмотрели реализацию глобальной обработки ошибок с помощью объекта config.errorHandler. А также локальный обработчик на основе хука errorCaptured.

Наталья Кайдаавтор-переводчик статьи «Error/Exception handling in Vue.js application»