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