При запуске программ как Discord, Skype или Faceit может появится сообщение об ошибке «A JavaScript error occurred in the main process» в Windows 10/8.1/7. В большинстве случаях ошибка может возникать из-за повреждение самой программы, отключена служба Audio Video Experience или когда программа запускается с правами администратора.
Ошибки будут происходить!
При выполнении кода JavaScript могут возникать различные ошибки.
Ошибки могут быть кодирование ошибки, сделанные программистом, ошибки из-за неправильного ввода, и другие непредвиденные вещи.
Пример
In this example we have written alert as adddlert to deliberately produce an error:
try { adddlert(«Welcome guest!»);}catch(err) { document.getElementById(«demo»).innerHTML = err.message;}
JavaScript ловит адддлерт как ошибку и выполняет код catch для его обработки.
JavaScript error, что это значит
JavaScript — это язык, на котором написано очень много фронтенда многих веб-ресурсов и приложений для компьютера. Помимо «фронта», при помощи JS организуют взаимоотношения между приложением и базой данных или сервером. Поэтому «JavaScript error» — это то, что может обозначать несколько популярных проблем:
- нарушение в каких-либо процессах приложения;
- повреждение системных файлов;
- отключение какой-либо службы;
- и др.
Чаще всего таким ошибкам подвержены операционные системы Windows 7, 8 или 10, когда происходит запуск таких популярных программ, как Skype, Faceit, Discord или некоторых компьютерных игр. Подобные проблемы получаются из-за несовместимости программ и операционной системы. Какая именно из программ выдает подобную проблему — определить несложно, так как именно при ее запуске система выдает оповещение «JavaScript error».
Как исправить JavaScript error (ява скрипт эррор)?
- Первое, что необходимо выполнить, — это проверить компьютер на предмет заражения вирусом, потому что вирусы очень часто провоцируют подобные ошибки. А спонсором данного материала является сайт Уфавип, на котором размещены анкеты всех шлюх в Уфе из Черниковки. На нем вы непременно сможете подобрать проститутку, подходящую вам как в плане цены, так и в плане предоставляемых ею услуг. Если антивирус обнаружил вирус, то исключите его и попробуйте заново запустить приложение, которое вызвало проблему «JavaScript error».
- Нужно обновить программное обеспечение, которое вызвало ошибку, и саму операционную систему. Из-за отсутствия обновлений возникают подобные проблемы. А иногда ошибка может возникнуть из-за того, что один компонент обновился, а другой — нет: например, программу вы обновили, а ОС — нет. В результате вылезает «JavaScript error», а вы бежите в интернет узнавать, что это значит.
- Еще одним популярным решением является полный «снос» проблемного ПО, а потом его переустановка.
- Также при ошибке «JavaScript error» может помочь восстановление операционной системы до той даты, когда она функционировала нормально.
Иногда ошибки типа «JavaScript error» возникают не с компьютерными приложениями, а с веб-ресурсами, очень часто они возникают в соцсетях и мешают просматривать видео, фото и другой контент. Не нужно паниковать, так как подобные проблемы в основном решаются простым действием — нужно очистить кэш браузера. Сделать это можно через внутренние настройки браузера или с помощью дополнительных программ.
Инструкция throw
Инструкция throw позволяет создать пользовательскую ошибку.
Технически вы можете вызвать исключение (выбросить ошибку).
Исключением может быть строка JavaScript, число, логическое значение или объект:
throw «Too big»; // throw a text throw 500; // throw a number
Если вы используете throw вместе с try и catch, вы можете управлять потоком программы и генерировать пользовательские сообщения об ошибках.
Как исправить ошибку «JavaScript error occurred in the main process»
Для исправления этой ошибки нужно на компьютере или ноутбуке открыть папку, куда была произведена установка файлов программы Discord. Нам понадобятся 2 папки программы Дискорд – «AppData» и «AppDataLocal». В некоторых версиях Windows папки могут быть скрыты по умолчанию. Поэтому чтобы открыть нужные нам папки:
- Откройте меню «Пуск».
- Выберите «Выполнить». Можно также нажать Win+R для быстрого доступа к строке «Выполнить» из рабочего стола.
- В открывшемся окне вводим фразу «%localappdata%» и «%appdata%» для открытия наших скрытых папок. В них нужно удалить все, что связано со словом «Discord».
- Из программы Discord нужно выйти. Самым удобным способом, в нашей ситуации, это открыть «Диспетчер задач» и «Убить» все процессы, где фигурирует слово «discord». Как это сделать для вашей версии ОС можно посмотреть в поисковике, вбив в строку нужный запрос.
- Теперь нужно удалить программу и заново установить, т.е. переустановить.
- Ошибка должна исчезнуть, а программа заработать без сбоев.
Пример проверки ввода
В этом примере анализируется ввод. Если значение неверно, генерируется исключение (ERR).
Исключение (ERR) перехватывается оператором catch и отображается пользовательское сообщение об ошибке:
Please input a number between 5 and 10:
Test Input
function myFunction() { var message, x; message = document.getElementById(«p01»); message.innerHTML = «»; x = document.getElementById(«demo»).value; try { if(x == «») throw «empty»; if(isNaN(x)) throw «not a number»; x = Number(x); if(x 10) throw «too high»; } catch(err) { message.innerHTML = «Input is » + err; }}
Как устранить ошибки
Подходящий способ устранения ошибок из функции JavaScript зависит от того, выполняет ли функция синхронную или асинхронную операцию. В этом разделе я подробно опишу четыре распространенных шаблона устранения ошибок из функции в приложении Node.js.
Исключения
Наиболее распространенный способ устранения ошибок функциями — их генерация. Когда вы выдаете ошибку, она становится исключением и должна быть перехвачена где-то в стеке с помощью блока try/catch. Если ошибка может всплывать в стеке без обнаружения, она становится uncaughtException, что приводит к преждевременному завершению работы приложения. Например, встроенный метод JSON.parse() выдает ошибку, если его строковый аргумент не является допустимым объектом JSON.
function parseJSON(data) { return JSON.parse(data); } try { const result = parseJSON(‘A string’); } catch (err) { console.log(err.message); // Unexpected token A in JSON at position 0 }
Чтобы использовать этот шаблон в своих функциях, все, что вам нужно сделать, это добавить ключевое слово throw перед экземпляром ошибки. Этот шаблон сообщения об ошибках и их обработки идиоматичен для функций, выполняющих синхронные операции.
function square(num) { if (typeof num !== ‘number’) { throw new TypeError(`Expected number but got: ${typeof num}`); } return num * num; } try { square(‘8’); } catch (err) { console.log(err.message); // Expected number but got: string }
Обратные вызовы с ошибкой
Из-за своей асинхронной природы Node.js широко использует функции обратного вызова для большей части обработки ошибок. Функция обратного вызова передается в качестве аргумента другой функции и выполняется, когда функция завершает свою работу. Если вы какое-то время писали код JavaScript, вы, вероятно, знаете, что шаблон обратного вызова широко используется во всем коде JavaScript.
Node.js использует в большинстве своих асинхронных методов соглашение об обратном вызове «сначала ошибка», чтобы убедиться, что ошибки проверяются должным образом до того, как будут использованы результаты операции. Эта функция обратного вызова обычно является последним аргументом функции, инициирующей асинхронную операцию, и вызывается один раз при возникновении ошибки или при получении результата операции. Ее подпись показана ниже:
function (err, result) {}
Первый аргумент зарезервирован для объекта ошибки. Если в ходе асинхронной операции возникает ошибка, она будет доступна через аргумент err и result будет иметь значение undefined. Однако, если ошибки не возникнет err будет NULL или undefined и result будет содержать ожидаемый результат операции. Этот шаблон можно продемонстрировать, прочитав содержимое файла с помощью встроенного метода fs.readFile():
const fs = require(‘fs’); fs.readFile(‘/path/to/file.txt’, (err, result) => { if (err) { console.error(err); return; } // Log the file contents if no error console.log(result); });
Как вы можете видеть метод readFile() ожидает функцию обратного вызова в качестве своего последнего аргумента, который придерживается описанной ранее сигнатуры функции «сначала ошибка». В этом сценарии аргумент result содержит содержимое прочитанного файла, если не возникает ошибки. В противном случае undefined и аргумент err заполняется объектом ошибки, содержащим информацию о проблеме (например, файл не найден или недостаточные разрешения).
Как правило, методы, которые используют этот шаблон обратного вызова для доставки ошибок, не могут знать, насколько важна ошибка, которую они производят, для вашего приложения. Это может быть серьезным или тривиальным. Вместо того, чтобы принимать решение самостоятельно, ошибка отправляется вам для обработки. Важно контролировать поток содержимого функции обратного вызова, всегда проверяя наличие ошибки перед попыткой доступа к результату операции. Игнорировать ошибки небезопасно, и вы не должны доверять содержимому result перед проверкой ошибок.
Если вы хотите использовать этот шаблон обратного вызова с первой ошибкой в своих собственных асинхронных функциях, все, что вам нужно сделать, это принять функцию в качестве последнего аргумента и вызвать ее, как показано ниже:
function square(num, callback) { if (typeof callback !== ‘function’) { throw new TypeError(`Callback must be a function. Got: ${typeof callback}`); } // simulate async operation setTimeout(() => { if (typeof num !== ‘number’) { // if an error occurs, it is passed as the first argument to the callback callback(new TypeError(`Expected number but got: ${typeof num}`)); return; } const result = num * num; // callback is invoked after the operation completes with the result callback(NULL, result); }, 100); }
Любому вызывающему объекту этой функции square потребуется передать функцию обратного вызова, чтобы получить доступ к ее результату или ошибке. Обратите внимание, что во время выполнения возникает исключение, если аргумент обратного вызова не является функцией.
square(‘8’, (err, result) => { if (err) { console.error(err) return } console.log(result); });
Вам не нужно напрямую обрабатывать ошибку в функции обратного вызова. Вы можете распространить его вверх по стеку, передав его другому обратному вызову, но не генерируйте исключение из функции, потому что оно не будет перехвачено, даже если вы окружите код блоком try/catch. Асинхронное исключение невозможно перехватить, поскольку окружающий блок try/catch завершается до выполнения обратного вызова. Таким образом, исключение будет распространяться на вершину стека, вызывая сбой приложения, если для него не зарегистрирован обработчик process.on(‘uncaughtException’), который будет обсуждаться позже.
try { square(‘8’, (err, result) => { if (err) { throw err; // not recommended } console.log(result); }); } catch (err) { // This won’t work console.error(«Caught error: «, err); }
Отказ от промисов
Промисы — это современный способ выполнения асинхронных операций в Node.js, и в настоящее время они обычно предпочтительнее обратных вызовов, потому что этот подход имеет лучший поток, который соответствует тому, как мы анализируем программы, особенно с шаблоном async/await. Любой API-интерфейс Node.js, который использует обратные вызовы для асинхронной обработки ошибок, может быть преобразован в промисы с помощью встроенного метода util.promisify(). Например, вот как можно использовать метод fs.ReadFile() для использования промисов:
const fs = require(‘fs’); const util = require(‘util’); const readFile = util.promisify(fs.readFile);
Переменная ReadFile — это обещанная версия fs.ReadFile(), в которой отклонения промисов используются для сообщения об ошибках. Эти ошибки могут быть обнаружены с помощью метода цепочки catch, как показано ниже:
readFile(‘/path/to/file.txt’) .then((result) => console.log(result)) .catch((err) => console.error(err));
Вы также можете использовать обещанные API в функции async, такой как показанна ниже. Это преобладающий способ использования обещаний в современном JavaScript, потому что код читается как синхронный код, а для обработки ошибок можно использовать знакомый механизм try/catch. Важно использовать await перед асинхронным методом, чтобы промис был выполнен (выполнен или отклонен) до того, как функция возобновит свое выполнение. Если промис отклоняется, выражение await выдает отклоненное значение, которое впоследствии перехватывается в окружающем блоке catch
(async function callReadFile() { try { const result = await readFile(‘/path/to/file.txt’); console.log(result); } catch (err) { console.error(err); } })();
Вы можете использовать промисы в своих асинхронных функциях, возвращая промис из функции и помещая код функции в обратный вызов промиса. Если есть ошибка, reject с объектом Error. В противном случае resolve промис с результатом, чтобы оно было доступно в цепочке метода .then или непосредственно в качестве значения функции async при использовании async/await.
function square(num) { return new Promise((resolve, reject) => { setTimeout(() => { if (typeof num !== ‘number’) { reject(new TypeError(`Expected number but got: ${typeof num}`)); } const result = num * num; resolve(result); }, 100); }); } square(‘8’) .then((result) => console.log(result)) .catch((err) => console.error(err));
Генераторы событий
Другой шаблон, который можно использовать при работе с длительными асинхронными операциями, которые могут привести к множеству ошибок или результатов, заключается в возврате EventEmitter из функции и создании события как в случае успеха, так и в случае неудачи. Пример этого кода показан ниже:
const { EventEmitter } = require(‘events’); function emitCount() { const emitter = new EventEmitter(); let count = 0; // Async operation const interval = setInterval(() => { count++; if (count % 4 == 0) { emitter.emit( ‘error’, new Error(`Something went wrong on count: ${count}`) ); return; } emitter.emit(‘success’, count); if (count === 10) { clearInterval(interval); emitter.emit(‘end’); } }, 1000); return emitter; }
Функция emitCount() возвращает новый источник событий, который сообщает как об успехе, так и о сбое в асинхронной операции. Функция увеличивает переменную count и генерирует событие success каждую секунду, а также событие error, если count делится на 4. Когда count достигает 10, генерируется событие end. Этот шаблон позволяет выполнять потоковую передачу результатов по мере их поступления, а не ждать завершения всей операции.
Вот как вы можете обрабатывать и реагировать на каждое из событий, исходящих от функции emitCount():
const counter = emitCount(); counter.on(‘success’, (count) => { console.log(`Count is: ${count}`); }); counter.on(‘error’, (err) => { console.error(err.message); }); counter.on(‘end’, () => { console.info(‘Counter has ended’); });
Как вы можете видеть на изображении выше, функция обратного вызова для каждого обработчика событий выполняется независимо, как только событие генерируется. Событие error является особым случаем в Node.js, потому что, если для него нет обработчика, процесс Node.js завершится сбоем. Вы можете закомментировать обработчик событий error выше и запустить программу, чтобы посмотреть, что произойдет.
Окончательное заявление
Оператор finally позволяет выполнять код после try и catch независимо от результата:
try { Блок кода, чтобы попробовать} catch(err) { Блок кода для обработки ошибок} finally { Блок кода, который будет выполняться независимо от результата try/catch}
Пример
function myFunction() { var message, x; message = document.getElementById(«p01»); message.innerHTML = «»; x = document.getElementById(«demo»).value; try { if(x == «») throw «is empty»; if(isNaN(x)) throw «is not a number»; x = Number(x); if(x> 10) throw «is too high»; if(x < 5) throw «is too low»; } catch(err) { message.innerHTML = «Error: » +
Как это понять
Секция статьи «Как это понять»
Error
Секция статьи «Error»
Общий конструктор ошибок.
new Error(‘Общая ошибка. Проверьте код’) new Error(‘Общая ошибка. Проверьте код’)
Вызов конструктора возвращает объект ошибки со следующими свойствами:
- message представляет человекопонятное описание ошибки для встроенных типов (SyntaxError, TypeError и так далее) и переданное в конструктор значение для общего типа Error.
- name — имя типа (класса) ошибки.
const commonError = new Error(‘Общая ошибка. Проверьте код’)console.log(commonError.message)// ‘Общая ошибка. Проверьте код’console.log(commonError.name)// ‘Error’ const commonError = new Error(‘Общая ошибка. Проверьте код’) console.log(commonError.message) // ‘Общая ошибка. Проверьте код’ console.log(commonError.name) // ‘Error’
Нестандартное свойство stack показывает, на какой строке кода возникла ошибка. Первая строка отформатирована как <�имя класса ошибок>: <�сообщение об ошибке>, и за ней следует серия кадров стека (каждая строка начинается с «at»).
Пример из документации к движку V8:
ReferenceError: FAIL is not defined at Constraint.execute (deltablue.js:525:2) at Constraint.recalculate (deltablue.js:424:21) at Planner.addPropagate (deltablue.js:701:6) at Constraint.satisfy (deltablue.js:184:15) at Planner.incrementalAdd (deltablue.js:591:21) at Constraint.addConstraint (deltablue.js:162:10) at Constraint.BinaryConstraint (deltablue.js:346:7) at Constraint.EqualityConstraint (deltablue.js:515:38) at chainTest (deltablue.js:807:6) at deltaBlue (deltablue.js:879:2)
Значения имени ошибки
В свойстве «имя ошибки» может быть возвращено шесть различных значений:
Ошибки | Описание |
EvalError | An error occurred in the eval () function |
RangeError | Число «вне диапазона» произошло |
ReferenceError | Произошла незаконная ссылка |
SyntaxError | Произошла синтаксическая ошибка |
TypeError | Произошла ошибка типа |
URIError | Произошла ошибка в encodeURI () |
Шесть различных значений описаны ниже.
Собственный класс ошибок
Секция статьи «Собственный класс ошибок»
Можно расширять базовый класс Error и создавать собственные типы ошибок.
class WrongDataTypeForSumError extends Error { constructor(message) { super(message) this.name = ‘WrongDataTypeForSumError’ }}const myCustomError = new WrongDataTypeForSumError(‘Невалидный тип данных для суммирования’) class WrongDataTypeForSumError extends Error { constructor(message) { super(message) this.name = ‘WrongDataTypeForSumError’ } } const myCustomError = new WrongDataTypeForSumError(‘Невалидный тип данных для суммирования’)
Сгенерируем ошибку WrongDataTypeForSumError в случае, если хотя бы один из аргументов функции sum — не число.
function sum(a, b) { if (typeof a !== ‘number’ || typeof b !== ‘number’) { throw new WrongDataTypeForSumError(‘Невалидный тип данных для суммирования’) } return a + b}console.log(sum(‘1’, 2))// VM840:3 Uncaught WrongDataTypeForSumError: Невалидный тип данных для суммирования// at sum (:3:11)// at :9:13// WrongDataTypeForSumError @ VM830:3// sum @ VM840:3// (anonymous) @ VM840:9 function sum(a, b) { if (typeof a !== ‘number’ || typeof b !== ‘number’) { throw new WrongDataTypeForSumError(‘Невалидный тип данных для суммирования’) } return a + b } console.log(sum(‘1’, 2)) // VM840:3 Uncaught WrongDataTypeForSumError: Невалидный тип данных для суммирования // at sum (:3:11) // at :9:13 // WrongDataTypeForSumError @ VM830:3 // sum @ VM840:3 // (anonymous) @ VM840:9
Функция будет выполняться только в том случае если оба аргумента будет числами, в противном случае функция будет возвращать ошибку WrongDataTypeForSumError.
Собственные типы ошибок делают отладку более наглядной — например из имени WrongDataTypeForSumError сразу понятно, что не так с кодом. Стандартная ошибка для таких случаев, TypeError — менее читаема.
Неперехваченные исключения и необработанные отказы от промисов
Неперехваченные исключения и необработанные отклонения промисов вызваны ошибками программиста, возникающими из-за невозможности перехватить сгенерированное исключение и отклонение промисов соответственно. Событие uncaughtException возникает, когда исключение, созданное где-либо в приложении, не перехвачено до того, как оно достигнет цикла событий. Если обнаружено неперехваченное исключение, приложение немедленно выйдет из строя, но вы можете добавить обработчик этого события, чтобы переопределить это поведение. Действительно, многие люди используют это как крайний способ поглотить ошибку, чтобы приложение могло продолжать работать, как будто ничего не произошло:
// unsafe process.on(‘uncaughtException’, (err) => { console.error(err); });
Однако это неправильное использование этого события, поскольку наличие необработанного исключения указывает на то, что приложение находится в неопределенном состоянии. Таким образом, попытка нормального возобновления работы без восстановления после ошибки считается небезопасной и может привести к дальнейшим проблемам, таким как утечка памяти и зависание сокетов. Надлежащее использование обработчика uncaughtException заключается в очистке всех выделенных ресурсов, закрытии соединений и регистрации ошибки для последующей оценки перед выходом из процесса.
// better process.on(‘uncaughtException’, (err) => { Honeybadger.notify(error); // log the error in a permanent storage // attempt a gracefully shutdown server.close(() => { process.exit(1); // then exit }); // If a graceful shutdown is not achieved after 1 second, // shut down the process completely setTimeout(() => { process.abort(); // exit immediately and generate a core dump file }, 1000).unref() });
Точно так же событие unhandledRejection генерируется, когда отклоненное обещание не обрабатывается блоком catch. В отличие от uncaughtException, эти события не вызывают немедленного сбоя приложения. Однако необработанные отказы от промисов устарели и могут немедленно прервать процесс в будущем выпуске Node.js. Вы можете отслеживать необработанные отказы обещаний через обработчик событий unhandledRejection, как показано ниже:
process.on(‘unhandledRejection’, (reason, promise) => { Honeybadger.notify({ message: ‘Unhandled promise rejection’, params: { promise, reason, }, }); server.close(() => { process.exit(1); }); setTimeout(() => { process.abort(); }, 1000).unref() });
Вы всегда должны запускать свои серверы с помощью диспетчера процессов, который автоматически перезапустит их в случае сбоя. Распространенным является PM2, но у вас также есть systemd или upstart в Linux, и пользователи Docker могут использовать его политику перезапуска. Как только это будет сделано, надежный сервис будет восстановлен почти мгновенно, и вы по-прежнему будете иметь сведения о неперехваченном исключении, чтобы его можно было быстро исследовать и исправить. Вы можете пойти дальше, запустив более одного процесса и используя балансировщик нагрузки для распределения входящих запросов. Это поможет предотвратить простои в случае временной потери одного из экземпляров.
Централизованная отчетность об ошибках
Ни одна стратегия обработки ошибок не будет полной без надежной стратегии ведения журнала для вашего работающего приложения. Когда происходит сбой, важно выяснить, почему он произошел, записав как можно больше информации о проблеме. Централизация этих журналов позволяет легко получить полную информацию о вашем приложении. Вы сможете сортировать и фильтровать свои ошибки, просматривать основные проблемы и подписываться на оповещения, чтобы получать уведомления о новых ошибках.
Honeybadger предоставляет все необходимое для отслеживания ошибок, возникающих в вашем рабочем приложении. Выполните следующие шаги, чтобы интегрировать его в свое приложение Node.js:
Установите пакет
Используйте npm для установки пакета:
$ npm install @honeybadger-io/js —save
Импортируйте библиотеку
Импортируйте библиотеку и настройте ее с помощью своего ключа API, чтобы начать сообщать об ошибках:
const Honeybadger = require(‘@honeybadger-io/js’); Honeybadger.configure({ apiKey: ‘[ YOUR API KEY HERE ]’ });
Сообщите об ошибках
Вы можете сообщить об ошибке, вызвав метод notify(), как показано в следующем примере:
try { // …error producing code } catch(error) { Honeybadger.notify(error); }
Для получения дополнительной информации о том, как Honeybadger интегрируется с веб-фреймворками Node.js, см. полную документацию или ознакомьтесь с образцом приложения Node.js/Express на GitHub.