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

Теория

Необходимо создать службу, которая будет активна с момента запуска Vue до закрытия страницы. Поэтому для этой службы необходимо использовать шаблон Singleton. Это означает, что в приложении будет доступен только один экземпляр службы. Также необходимо использовать этот шаблон, потому что в приложении не должно быть конфликтов, пока будут обрабатываться ошибки.

Обработка ошибок - хранение их в отдельном сервисе для разработчиков. Необходимо написать интерфейс, который мог бы передавать ошибки в эту службу. Отдельным сервисом будет sentry.io или другой собственный сервер. Наша задача - просто передать ошибки на сервер без потерь.

Создать приложение

В качестве шаблона приложения выбираю свой на основе компонентов машинописного текста + декораторов (ссылка на шаблон).

  • Также вы можете перевести код на JavaScript ES6. Он будет работать как в TypeScript

Кодирование

Создать сервис

Начнем с JavaScript-класса на основе одноэлементного шаблона. Мы воспользуемся одним из самых популярных способов.

export class ErrorsService {
  private static shared = new ErrorsService();
  
  static get instance() {
    return this.shared;
  }
  constructor() {
  }
}

Далее нужно написать какой-нибудь поток ошибок. Для этого функционала я буду использовать rx.js. Вы могли бы использовать что-нибудь другое. Это не имеет значения.

export class ErrorsService {
  private static shared = new ErrorsService();
  
  public errors$: Observable<Error>;
  private errorsStream$ = new ReplaySubject<Error>(1);
  public static get instance() {
    return this.shared;
  }
  constructor() { 
    this.errors$ = this.errorsStream$.asObservable(); 
  }
}
  • Примечание. Очень важно разделять Observer и Observable, потому что необходимо защитить любые push-уведомления для потоковой передачи.

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

public onError(error: Error) {
  this.errorsStream$.next(error);
}
private initHandler() {
  const scope = this;
  window.onerror = (message: Event | string, url?: string, lineNo?: number, columnNo?: number, error?: Error) => {
    if (error) scope.onError(error);
  };
}

Теперь у нас есть две функции. Первая функция «При ошибке» выдает ошибку и отправляет ее в поток. Также эта функция будет содержать некоторые правила для ошибок (они будут написаны дальше). Вторая функция «initHandler» добавляет прослушиватель событий окна «error», который будет перехватывать почти все ошибки в приложении.

  • Примечание: window.onerror не перехватывает все ошибки. Поэтому иногда приходится отправлять ошибки в сервис вручную.

Обработка ошибок Vue.js

Обработка ошибок окна не обеспечивает обработку ошибок Vue.js (например, ошибок при монтировании компонента). Так что нужно рассказать Vue.js - как обрабатывать ошибки. Откройте файл main.ts и напишите следующее:

Vue.config.errorHandler = (error) => ErrorsService.getInstance.onError(error);

Обработка ошибок http

Часть ошибок http не означает ничего плохого. Например, статус 400, который обычно используется в методах POST, означает неправильное заполнение данных, и служба не должна отправлять их на сервер. Поэтому нужно пропустить все статусы ошибок http в обработчике. Это все статусы от 400 до 404 (доказательство). На мой взгляд, другие статусы 4xx должны быть ошибочными. Например. обработка аксиомов:

onError(error: Error) {
  const response = (error as AxiosError).response;
  if (response && response.status >= 400 && response.status < 405) {
    return false;
  }
  this.errorsStream$.next(error);
}

Отправить ошибки на сервер

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

// App.ts
...
mounted() {
ErrorsService.errors$
  .pipe(flatMap(error => httpClient.post('/somepath', error)))
  .subscribe();
}
...

Заключение

У нас есть сервис, который может обрабатывать ручные, оконные и Vue.js ошибки, фильтровать их и отправлять на сервер. Мысли об увеличении производительности и удобства использования: используйте Worker для разделения потока на уровне ОС, используйте ServiceWorker для обработки ошибок push-уведомлений.

Спасибо за чтение!

Наш телеграм-канал: https://t.me/frontend_html_css_js