Vue предоставляет механизм глобальной и локальной обработки ошибок
через хуки жизненного цикла компонентов, одним из которых является
errorCaptured. Этот хук позволяет перехватывать ошибки,
возникающие в дочерних компонентах, предотвращая их всплытие до
глобального обработчика. В контексте тестирования компонентов с
использованием Vue Test Utils,
errorCaptured становится мощным инструментом для проверки
устойчивости компонентов к ошибкам.
errorCapturedХук errorCaptured вызывается автоматически при
возникновении ошибки в любом дочернем компоненте. Он принимает три
аргумента:
Возвращаемое значение хука определяет дальнейшую судьбу ошибки:
true — ошибка считается обработанной, дальнейшее
всплытие прекращается.false или отсутствие возврата — ошибка продолжает
всплывать и может быть поймана глобальным обработчиком Vue.Пример использования внутри компонента:
export default {
name: 'ParentComponent',
errorCaptured(err, vm, info) {
console.error('Ошибка поймана в ParentComponent:', err.message, info);
return true; // предотвращает дальнейшее всплытие
}
}
Vue Test Utils предоставляет инструменты для
создания экземпляров компонентов и симуляции событий, включая ошибки.
Основной подход к тестированию errorCaptured состоит из
следующих шагов:
errorCaptured.errorCaptured был вызван и корректно
обработал ошибку.Пример теста с использованием Jest:
import { mount } from '@vue/test-utils';
import ParentComponent from '@/components/ParentComponent.vue';
import ChildComponent from '@/components/ChildComponent.vue';
const ErrorThrowingChild = {
template: '<div></div>',
mounted() {
throw new Error('Test error');
}
};
test('errorCaptured перехватывает ошибку дочернего компонента', () => {
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const wrapper = mount(ParentComponent, {
global: {
components: {
ChildComponent: ErrorThrowingChild
}
}
});
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining('Ошибка поймана в ParentComponent:'),
expect.stringContaining('Test error'),
expect.any(String)
);
consoleSpy.mockRestore();
});
В данном примере:
ErrorThrowingChild, выбрасывающая
ошибку при монтировании.jest.spyOn контролируется вызов
console.error, что позволяет убедиться, что ошибка была
перехвачена.errorCaptured предотвращает глобальный сбой теста,
возвращая true.Ошибки в асинхронных методах, таких как mounted с
async/await, также можно перехватывать через
errorCaptured. Для корректного тестирования таких случаев
необходимо использовать flushPromises для ожидания
завершения всех промисов.
Пример:
import { mount, flushPromises } from '@vue/test-utils';
const AsyncChild = {
template: '<div></div>',
async mounted() {
await Promise.reject(new Error('Async error'));
}
};
test('errorCaptured перехватывает асинхронные ошибки', async () => {
const wrapper = mount(ParentComponent, {
global: {
components: { AsyncChild }
}
});
await flushPromises();
expect(wrapper.vm.errorHandled).toBe(true); // предполагается, что родитель устанавливает флаг
});
Vue позволяет задавать глобальный обработчик ошибок через
app.config.errorHandler. В тестах важно различать локальный
и глобальный обработчик:
errorCaptured вызывается первым.true, глобальный
обработчик не срабатывает.false или отсутствует,
ошибка передается глобальному обработчику.Это поведение позволяет в тестах проверять как локальную обработку ошибок, так и взаимодействие с глобальной системой логирования или уведомлений.
errorCaptured, чтобы предотвращать падение всего
приложения при ошибках дочерних компонентов.err, vm и
info позволяет убедиться, что ошибка обработана корректно и
информация о ней сохраняется.flushPromises
или аналогичных механизмов ожидания завершения промисов.falseТестирование случая, когда errorCaptured возвращает
false, важно для проверки передачи ошибки глобальному
обработчику:
test('ошибка продолжает всплывать при return false', () => {
const globalHandler = jest.fn();
const wrapper = mount(ParentComponent, {
global: {
config: {
errorHandler: globalHandler
},
stubs: {
ChildComponent: {
template: '<div></div>',
mounted() { throw new Error('Bubble error'); }
}
}
}
});
wrapper.vm.errorCaptured = () => false;
expect(globalHandler).toHaveBeenCalledWith(
expect.any(Error),
expect.any(Object),
expect.any(String)
);
});
Такой подход позволяет моделировать и проверять сценарии, когда компонент не должен блокировать глобальную обработку ошибок.
Использование errorCaptured совместно с Vue Test Utils
позволяет:
Это делает errorCaptured ключевым инструментом при
разработке надежных и тестируемых Vue-компонентов.