Haunted — это библиотека для создания веб-компонентов с
использованием функционального подхода и реактивного состояния в стиле
Hooks. Одной из важных задач при разработке компонентов является
грамотная обработка ошибок, возникающих как в процессе рендеринга, так и
при взаимодействии с асинхронными данными. В Haunted нет встроенной
системы обработки ошибок уровня фреймворка, как в React с
ErrorBoundary, поэтому требуется понимание того, как
интегрировать обработку ошибок на уровне хуков и компонентов.
В Haunted рендеринг компонентов основан на функции, возвращающей
шаблон HTML через html из библиотеки lit-html.
Любые синтаксические ошибки или исключения в логике функции-компонента
приведут к остановке рендеринга. Для безопасного рендеринга можно
использовать конструкцию try/catch внутри компонента:
import { html } from 'haunted';
function SafeComponent({ data }) {
try {
if (!data) throw new Error('Данные не определены');
return html`<p>Значение: ${data}</p>`;
} catch (err) {
console.error('Ошибка в SafeComponent:', err);
return html`<p>Произошла ошибка при отображении данных.</p>`;
}
}
Особенности подхода:
Компоненты Haunted часто используют асинхронные операции для
получения данных. Для таких случаев обработка ошибок должна выполняться
внутри асинхронных функций или хуков состояния (useState,
useEffect). Пример использования асинхронного хука с
обработкой ошибок:
import { html } from 'haunted';
import { useState, useEffect } from 'haunted';
function AsyncComponent({ url }) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`Ошибка HTTP: ${response.status}`);
const result = await response.json();
if (isMounted) setData(result);
} catch (err) {
if (isMounted) setError(err);
}
}
fetchData();
return () => { isMounted = false; };
}, [url]);
if (error) return html`<p>Ошибка загрузки: ${error.message}</p>`;
if (!data) return html`<p>Загрузка...</p>`;
return html`<p>Данные получены: ${JSON.stringify(data)}</p>`;
}
Ключевые моменты:
try/catch внутри асинхронной функции для
перехвата ошибок.error хранит информацию о проблеме, позволяя
рендерить fallback UI.isMounted предотвращает попытку изменения
состояния после размонтирования компонента.Для крупных приложений удобно создавать обёртки, выполняющие функции «Error Boundary». В Haunted это можно реализовать через компонент высшего порядка (HOC) или специальный хук. Пример HOC:
import { html } from 'haunted';
function withErrorBoundary(Component) {
return function ErrorBoundaryWrapper(props) {
try {
return Component(props);
} catch (err) {
console.error('Ошибка в компоненте:', err);
return html`<p>Произошла ошибка в приложении.</p>`;
}
};
}
const SafeAsyncComponent = withErrorBoundary(AsyncComponent);
Особенности HOC:
Ошибки могут возникать в обработчиках событий, таких как
click, input и других. В Haunted события
добавляются через стандартные слушатели DOM, поэтому обработка ошибок
сводится к привычным конструкциям try/catch:
function ButtonComponent() {
function handleClick() {
try {
// Возможная проблемная логика
throw new Error('Ошибка при нажатии');
} catch (err) {
console.error('Ошибка события:', err);
alert('Произошла ошибка при обработке действия');
}
}
return html`<button @click=${handleClick}>Нажми меня</button>`;
}
Особенности:
Для промышленных приложений важно не только отображать ошибки, но и
собирать их для анализа. Любые catch блоки можно
интегрировать с внешними сервисами:
catch (err) {
console.error(err);
sendErrorToMonitoringService(err);
}
Где sendErrorToMonitoringService — функция отправки
данных в систему мониторинга (Sentry, LogRocket и т. д.).
try/catch для критичных
операций внутри компонента.useState) для
асинхронных действий.Такой подход обеспечивает надежность компонентов Haunted и предотвращает поломку интерфейса при возникновении исключений.