Error tracking

Error tracking в Stencil является ключевым элементом обеспечения стабильности и надежности веб-компонентов. Stencil предоставляет встроенные механизмы для обработки ошибок на уровне компонентов и интеграции с внешними системами мониторинга. Основная цель — своевременно выявлять и локализовать ошибки, минимизируя влияние на пользовательский интерфейс.


Обработка ошибок в жизненном цикле компонента

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

  • componentWillLoad(): вызывается перед рендерингом компонента. Ошибки на этом этапе можно перехватывать через try...catch.
  • componentDidLoad(): вызывается после первого рендеринга. Позволяет проверять корректность состояния после инициализации.
  • componentShouldUpdate(newValue, oldValue, propName): позволяет контролировать обновление компонента. Ошибки здесь могут быть связаны с некорректной логикой сравнения свойств.
  • componentDidUpdate(): вызывается после обновления компонента. Используется для отслеживания изменений и возможных исключений при работе с DOM.

Пример перехвата ошибок в жизненном цикле:

@Component({
  tag: 'error-demo',
  styleUrl: 'error-demo.css',
  shadow: true,
})
export class ErrorDemo {
  @Prop() value: string;

  componentWillLoad() {
    try {
      this.validateValue(this.value);
    } catch (err) {
      console.error('Ошибка при загрузке компонента:', err);
    }
  }

  validateValue(value: string) {
    if (!value) {
      throw new Error('Свойство value не может быть пустым');
    }
  }
}

Глобальный перехват ошибок

Stencil поддерживает глобальный обработчик ошибок через window.onerror и window.addEventListener('unhandledrejection'). Это позволяет отслеживать как синхронные, так и асинхронные ошибки:

window.oner ror = (message, source, lineno, colno, error) => {
  console.error('Глобальная ошибка:', { message, source, lineno, colno, error });
};

window.addEventListener('unhandledrejection', event => {
  console.error('Необработанное отклонение промиса:', event.reason);
});

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


Интеграция с внешними сервисами мониторинга

Для профессионального отслеживания ошибок часто используют сервисы вроде Sentry, LogRocket или Rollbar. Stencil-компоненты легко интегрируются с такими сервисами, передавая информацию об ошибках:

import * as Sentry from '@sentry/browser';

Sentry.init({ dsn: 'YOUR_DSN_HERE' });

@Component({
  tag: 'sentry-demo',
  shadow: true,
})
export class SentryDemo {
  componentDidLoad() {
    try {
      this.riskyOperation();
    } catch (error) {
      Sentry.captureException(error);
    }
  }

  riskyOperation() {
    throw new Error('Демонстрационная ошибка');
  }
}

Ключевой момент — отправка максимально подробной информации: стек вызовов, состояние компонента, значения свойств и контекст пользователя.


Обработка ошибок при рендеринге

Stencil использует виртуальный DOM, и ошибки при рендеринге могут приводить к некорректному отображению компонентов. Для минимизации последствий рекомендуется использовать защитные блоки в методе render():

render() {
  try {
    return <div>{this.value.toUpperCase()}</div>;
  } catch (error) {
    console.error('Ошибка рендеринга:', error);
    return <div>Произошла ошибка отображения</div>;
  }
}

Это предотвращает полный сбой интерфейса и позволяет пользователю увидеть корректное fallback-сообщение.


Логирование состояния и событий

Для удобного отслеживания ошибок полезно вести журнал состояния компонента. В Stencil можно использовать как встроенные события (@Event), так и сторонние инструменты:

@Event() errorOccurred: EventEmitter<{ message: string; stack?: string }>;

emitError(error: Error) {
  this.errorOccurred.emit({ message: error.message, stack: error.stack });
}

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


Рекомендации по снижению числа ошибок

  • Проверка всех входных свойств через @Prop() с валидаторами.
  • Использование try...catch в критичных участках кода.
  • Применение TypeScript для строгой типизации.
  • Включение автоматического тестирования компонентов через Jest или Puppeteer.
  • Сегментирование ошибок на синхронные, асинхронные и жизненного цикла для удобного анализа.

Эти практики помогают строить стабильные и предсказуемые Stencil-приложения, где ошибки отслеживаются и локализуются максимально эффективно.