Javascript error как убрать эту ошибку

Время на прочтение
8 мин

Количество просмотров 12K

Всем привет! Вдохновленные успехом предыдущей статьи, которая была написана в преддверии запуска курса «Fullstack разработчик JavaScript«, мы решили продолжить серию статей для новичков и всех тех, кто только начинает заниматься программированием на языке JavaScript. Cегодня мы поговорим об ошибках, которые случаются в JS, а также о том, как именно с ними бороться.

Отдебажь за человека одну ошибку, и он будет благодарен тебе один пулл реквест. Научи его дебажить самостоятельно, и он будет благодарен тебе весь проект.

Неизвестный тимлид

Типичные ошибки начинающих

Итак, начнем с самых примитивных ошибок. Допустим, вы только недавно закончили изучать основы HTML и CSS и теперь активно принялись за программирование на JavaScript. Для примера: вы хотите, чтобы при клике на кнопку у вас открывалось, к примеру, скрытое до этого момента модальное окно. Так же вы хотите, чтобы у вас по нажатию на крестик это окно закрывалось. Интерактивный пример доступен здесь (я выбрал bitbucket из-за того, что его интерфейс мне кажется самым простым, да и не все же на гитхабе сидеть).

	let modal_alert = document.querySelector(".modal_alert")
	let hero__btn = document.querySelector(".hero__btn")
	let modal_close = document.querySelector(".modal-close ")
	//мы выбрали из DOM модели наши элементы. К слову, я использую bulma для упрощения процесса верстки

	//теперь мы хотим провести над нашими элементами какие-то операции:

	hero__btn.addEventListener("click", function(){
    	modal_alert.classList.add("helper_visible");
	})

	modal_close.addEventListener("click", function(){
    	modal_alert.classList.remove("helper_visible");
	})
//если мы хотим увидеть форму, то просто вешаем доп. класс, в котором прописано css-свойство display:flex. И наоборот, если хотим скрыть.

В нашем index.html, кроме верстки, мы внутри тэга head вставляем наш script:

	<script src="code.js"></script>

В index.html кроме верстки внутри тэга head мы вставляем наш script:

	<script src="code.js"></script>

Однако, несмотря на то, что мы все подключили, ничего не заработает и вылетит ошибка:

Что весьма печально, новички часто теряются и не понимают, что делать с красными строчками, словно это приговор какой-то, а не подсказка о том, что не так в вашей программе. Если перевести, то браузер говорит нам, что он не может прочитать свойство addEventListener нулевого значения. Значит, почему-то из DOM модели мы не получили наш элемент. Какой алгоритм действий нужно предпринять?

Во-первых, посмотрите в какой момент у вас вызывается javascript. Браузер читает ваш html-код сверху вниз, как вы читаете, например, книгу. Когда он увидит тэг script, то сразу исполнит его содержимое и продолжит чтение следующих элементов, не особо заботясь о том, что в своем скрипте вы пытаетесь получить элементы DOM, а он их еще не прочитал и, следовательно, не построил модель.

Что делать в таком случае? Просто добавьте атрибут defer внутрь вашего тэга скрипт (или async, но я не буду сейчас вдаваться в подробности их работы, это можно прочитать здесь ). Или можете просто переместить вниз ваш тэг script перед закрывающим body, это тоже сработает.

Во-вторых, проверьте опечатки. Изучите методологию БЭМ — она полезна ещё и тем, что вы хорошо знаете, как пишется ваш элемент — ведь пишите классы по единой логике, и стараетесь пользоваться только правильным английским языком. Или копируете сразу название элемента в JS файл.

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

Загадочная ошибка

Больше всего новичков вводит в ступор странная ошибка последней строчки кода. Приведем пример:

В консоли выводится что-то непонятное. Если переводить, то буквально это «Неожиданный конец ввода» — и что с этим делать? Кроме того, новичок по привычке смотрит на номер строки. На ней вроде все нормально. И почему тогда консоль на нее указывает?

Все просто. Что бы понимать, как интерпретировать вашу программу, интерпретатору JS нужно знать, где заканчивается тело функции, и где заканчивается тело цикла. В данном варианте кода я абсолютно намеренно забыл последнюю фигурную скобку:

	// тут у нас просто два массива с заголовками и статьями
	let root = document.getElementById("root"); // реактно подобно использую root
	let article__btn = document.querySelector("article__btn");
	// при клике на кнопку прочитаем статью
	
	article__btn.onclick = () => {
		for (let i = 0; i < headers.length; i++) {
			root.insertAdjacentHTML("beforeend", `
		<div class="content is-medium">
			<h1>${headers[i]} </h1>
			<p>${paragraps[i]}</p>
		</div>`)
		//изъятие фигурной скобки выполнено профессионалами. Не повторять на продакшене
	}

Теперь JavaScript не понимает, где у него конец тела функции, а где конец цикла и не может интерпретировать код.

Что делать в данном случае? В любом современном редакторе кода, если вы поставите курсор перед открывающей скобкой, подсветится его закрывающий вариант (если редактор еще не начал подчеркивать эту ошибку красным цветом). Просмотрите код еще раз внимательно, держа в голове, что в JS не бывает одиноких фигурных скобок. Проблемный вариант можно посмотреть здесь, а исправленный — вот тут.

Дробим код

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

Или как нормальный человек изучить TDD

К примеру, вам нужно простую программу, которая принимает данные на вход от пользователя, складывает их в массив и после этого выводит их средние значения:

	let input_number = prompt("Введите количество переменных");
	// определяем, какое количество переменных к нам придет
	let numbers = [];
	
	function toArray(input_number){
		for (let i = 0; i < input_number; i++) {
			let x = prompt(`Введите значение ${i}`);
			numbers.push(x); // и складываем значения в массив
		}
	}
	toArray(input_number); 
	
	function toAverage(numbers){
		let sum = 0;
		for (let i = 0; i < numbers.length; i++) {
			sum += numbers[i];
		}
		return sum/numbers.length;
	}
	alert(toAverage(numbers));

На первый неискушенный взгляд, в данном коде вполне все нормально. В нем есть основная логика, раздробленная на две функции, каждую из которой можно применять потом отдельно. Однако опытный программист сразу скажет, что это не заработает, ведь из prompt данные к нам приходят в виде строки. Причем JS (таков его толерантно-пофигистичный характер) нам все запустит, но на выходе выдаст настолько невероятную чепуху, что даже будет непросто понять, как мы дошли до жизни такой. Итак, давайте попробуем что-нибудь посчитать в нашем интерактивном примере. Введем допустим число 3 в количество переменных, и 1 2 3 в поле ввода данных:

Что? Чего? Ладно, это JavaScript. Поговорим лучше, как мы могли бы избежать такого странного вывода.

Надо было писать на Python, он бы по-человечески предупредил нас об ошибке

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

Вариант кода, в котором вероятность неожиданного вывода снижена:

	let input_number = prompt("Введите количество переменных");

	console.log(typeof(input_number));
	let numbers = [];
	
	function toArray(input_number){
		for (let i = 0; i < input_number; i++) {
			let x = prompt(`Введите значение ${i}`);
			numbers.push(x);
		}
	}

	toArray(input_number);
	console.log(numbers);
	
	function toAverage(numbers){
		let sum = 0;
		for (let i = 0; i < numbers.length; i++) {
			sum += numbers[i];
		}
		return sum/numbers.length;
	}
	console.log(typeof(toAverage(numbers)));
	alert(toAverage(numbers));

Иными словами, все подозрительные места, в которых что-то могло пойти не так, я вывел в консоль, чтобы убедиться, что все идет так, как я ожидаю. Конечно, данные console.log — детские игрушки и в норме, естественно, нужно изучить любую приличную библиотеку для тестирования. Например эту. Результат этой отладочной программы можно увидеть в инструментах разработчика здесь. Как починить, я думаю, вопросов не будет, но если если интересно, то вот (и да, это можно сделать просто двумя плюсами).

Шаг вперед: осваиваем Chrome Dev Tools

Дебаг с использованием console.log в 2019 — это уже несколько архаичная штука (но мы все равно ее никогда ее не забудем, она уже нам как родная). Каждый разработчик, который мечтает носить гордое звание профессионала, должен освоить богатый инструментарий современных средств разработки.

Попробуем починить проблемные места в нашем коде с помощью Dev Tools. Если нужна документация с примерами, всё можно прочитать вот здесь. А мы попробуем разобрать предыдущий пример с помощью Dev Tools.

Итак, открываем пример. У нас явно запрятался какой-то баг в коде, но как понять, в какой момент JavaScript начал что-то неправильно считать?

Правильно, оборачиваем эту радость тестами на тип переменной, это же очень просто

Идем во вкладку Sources в инструментах разработчика. Откройте файл code.js. У вас будут 3 части: первая слева, в которой отображается список файлов и вторая — в которой у нас отображается код. Но больше всего информации мы сможете почерпнуть из третьей части снизу, в которой отображается ход выполнения нашего кода. Давайте поставим breakpoint на 15 строчке (для этого надо щелкнуть по номеру строки в окне, где у нас отображается код, после чего у вас появится голубая метка). Перезапустите страницу, и введите любые значения в нашу программу.

Теперь вы можете вытащить из нижней панели debug массу полезной информации. Вы обнаружите, что JS не особенно задумываясь над типом переменных

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

складывает переменные в виде строки в наш массив. Теперь, осознав картину происходящего, мы можем принять контрмеры.

Учимся перехватывать ошибки

Конструкция try… catch встречается во всех современных языках программирования. Зачем эта синтаксическая конструкция нужна практически? Дело в том, что при возникновении ошибки в коде, он останавливает свое выполнение на месте ошибки — и все, дальнейшие инструкции интерпретатор не исполнит. В реально работающем приложении, из нескольких сотен строчек кода, нас это не устроит. И предположим, что мы хотим перехватить код ошибки, передать разработчику ее код, и продолжить выполнение дальше.

Наша статья была бы неполной без краткого описания основных типов ошибки в JavaScript:

  • Error — общий конструктор объекта ошибки.
  • EvalError — тип ошибки, появляющийся во время ошибок исполнения eval(), но не синтаксических, а при неправильном использовании этой глобальной функции.
  • RangeError — происходит, когда вы выходите за пределы допустимого диапазона в исполнении вашего кода.
  • ReferenceError — происходит, когда вы пытаетесь вызвать переменную, функцию или объект, которых нет в программе.
  • SyntaxError — ошибка в синтаксисе.
  • TypeError — происходит при попытке создания объекта с неизвестным типом переменной или при попытке вызова несуществующего метода
  • URIError — редко встречающий код, который возникает при неправильном использовании методов encodeURL и DecodeURL.

Здорово, давайте теперь немного попрактикуемся и посмотрим на практике, где мы можем использовать конструкцию try… catch. Сам принцип работы данной конструкции совсем простой — интерпретатор пытается исполнить код внутри try, если получается — то все продолжается, словно этой конструкции никогда не было. А вот если произошла ошибка — мы ее перехватываем и можем обработать, к примеру, сказав пользователю, где именно он допустил промах.

Давайте создадим самый простой калькулятор (даже калькулятором его называть громко, я бы сказал:«исполнитель введенных выражений»). Его интерактивный пример можно найти здесь. Хорошо, давайте теперь посмотрим на наш код:

	let input = document.querySelector("#enter");
	let button = document.querySelector("#enter_button");
	let result_el = document.querySelector("#result ");
	
	button.onclick = () => {
		try {
			let result = eval(input.value); //пробуем, если все будет корректно, тогда catch не сработает
			result_el.innerHTML = result;
		} catch (error) {
			console.error(error.name);
			result_el.innerHTML = "Вы что-то не то ввели, молодой человек<br> Подумайте еще раз";
			//можно пользователю объяснять, что он не прав, если он допустил ошибку
			//хотя естественно пользователю лучше не давать эту возможность))
		}
	}
 

Если вы попробуете ввести корректное математическое выражение, то все сработает нормально. Однако попробуйте ввести некорректное выражение, к примеру, просто строку, тогда программа выведет пользователю соответствующее предупреждение.

Надеюсь, вы прочитаете еще статьи, в которых объясняются другие части перехвата ошибок, такие например, как эта , чтобы расширить свое понимание в отладке программ, и изучите другие синтаксические конструкции, такие как finally, а также генерацию своих собственных ошибок.

На этом все. Надеюсь, эта статья оказалась полезна и теперь, при отладке приложений, вы будете чувствовать себя более уверенно. Мы разобрали типичные ошибки от самых элементарных, которые делают новички программирующие на JS всего несколько дней, до техники перехвата ошибок, которые применяют более продвинутые разработчики.

И по традиции, полезные ссылочки:

  • Пишем собственный фреймворк для тестирования. Полезно для общего понимания стратегии тестирования.
  • Полная документация по ошибкам, в том числе и экспериментальные фичи
  • Невероятно полезная статья на MDN, которая описывает большинство проблем, которые возникают в начале разработки на JS: отладку, полифиллы, дебагер и многое другое

На этом все. Ждем ваши комментарии и приглашаем на бесплатный вебинар, где поговорим о возможностях фреймворка SvelteJS.

Download Article

Download Article

If you’re seeing an error that says «a JavaScript error occurred in the main process» or «a fatal JavaScript error occurred» when trying to open or install Discord, there are several potential fixes. While these fixes are designed to resolve this error on Discord, they should work to resolve similar errors in other apps, including Microsoft Teams. We’ll show you how to troubleshoot JavaScript errors for Discord, Microsoft Teams, and other Windows 10 apps.

  1. Image titled Fix a Javascript Error in Windows 10 Step 1

    1

    Open your antivirus or antimalware software. If you’re unable to install Discord or another app on your PC because of a JavaScript error, such as «a JavaScript error occurred in the main process,» your antivirus software may be blocking the installer. You can fix this by adding an exclusion for the installer.

    • If you’re using Windows Security, which comes for free with Windows, type security into the search bar and then click Windows Security.
    • The remaining steps will cover unblocking an installer with Windows Security, but your antivirus suite may have different menu options.
  2. Image titled Fix a Javascript Error in Windows 10 Step 2

    2

    Go to the Virus and threat protection area. This gives you a general overview of your antivirus settings.

    Advertisement

  3. Image titled Fix a Javascript Error in Windows 10 Step 3

    3

    Click Manage settings. This opens the settings for your antivirus protection.

  4. Image titled Fix a Javascript Error in Windows 10 Step 4

    4

    Add an exclusion for the Discord installer. If you’re using Windows Security, click Add an exclusion, select File, and then open your download folder and select DiscordSetup.exe (or the name of the installer you’re trying to run).

  5. Image titled Fix a Javascript Error in Windows 10 Step 5

    5

    Run the installer again. Once you’ve allowed the installer to run, you should resolve JavaScript errors that occur during installation.

  6. Advertisement

  1. Image titled Fix a Javascript Error in Windows 10 Step 6

    1

    Close Discord (or the app you’re trying to fix). If you get a JavaScript error when trying to launch or install Discord or another app, the application data may be corrupt. If the app is running right now, you’ll want to close it so you can properly delete and reinstall it. Make sure it’s not minimized to your taskbar.

    • To be sure it’s closed, press Control + Alt + Delete and click Task Manager. If you see a that the app is running, click to select it, and then click End Task.[1]
    • Even if you’ve only tried installing the app and were not successful, you should still use this method before you try to install again.
  2. Image titled Fix a Javascript Error in Windows 10 Step 7

    2

    Press Win+S. This activates the Windows search bar.

  3. Image titled Fix a Javascript Error in Windows 10 Step 8

    3

    Type %appdata% and press Enter. This opens a File Explorer window to your application data.

  4. Image titled Fix a Javascript Error in Windows 10 Step 9

    4

    Permanently delete the folder for the app you’re trying to fix. For example, if you’re trying to fix Discord, you’ll want to delete the «Discord» folder. Here’s how:

    • Click the folder once to select it. Don’t open the folder—just select it for now.
    • Hold down the Shift key as you press Delete.
    • Click Yes.
  5. Image titled Fix a Javascript Error in Windows 10 Step 10

    5

    Press Win+S. This activates the Windows search bar again.

  6. Image titled Fix a Javascript Error in Windows 10 Step 11

    6

    Type %LocalAppData% and press Enter. This opens a File Explorer window to your local app data.

  7. Image titled Fix a Javascript Error in Windows 10 Step 12

    7

    Permanently delete the app’s folder here as well. Just hold down the Shift key as you press Delete, and then confirm deletion.

    • If you don’t see this folder, just skip this step.
  8. Image titled Fix a Javascript Error in Windows 10 Step 13

    8

    Uninstall Discord (or the app in question) from your PC. Here’s how:

    • Open the Windows menu and click the Settings gear.
    • Go to Apps > Apps & features.
    • Select the app and click Uninstall. If you don’t see the app here, just move to the next step.
    • Click Uninstall to confirm.
  9. Image titled Fix a Javascript Error in Windows 10 Step 14

    9

    Reinstall the app. If you’re reinstalling Discord, you can download the installer from https://discord.com/download. Once downloaded, double-click the installer and follow the on-screen instructions—this should fix just about all installation errors.

  10. Advertisement

  1. Image titled Fix a Javascript Error in Windows 10 Step 15

    1

    Open your Windows Settings

    Windows Settings

    . If you’re getting an error that says «a JavaScript error occurred in the main process» when trying to install Microsoft Teams, this may indicate a problem with the C++ libraries installed on your PC.[2]

    • While this method is known to work for Teams, it may also resolve the same issue in other apps.
  2. Image titled Fix a Javascript Error in Windows 10 Step 16

    2

    Click Apps. This opens the Settings panel to the Apps list.

  3. Image titled Fix a Javascript Error in Windows 10 Step 17

    3

    Click Apps & Features. This option is in the left panel.[3]

  4. Image titled Fix a Javascript Error in Windows 10 Step 18

    4

    Click the latest version of Microsoft Visual C++. You’ll probably see several instances of Visual ++ here—you’ll want to click the one that has the most recent date.

  5. Image titled Fix a Javascript Error in Windows 10 Step 19

    5

    Click Change or Advanced options. You should see one of these two options here.

  6. Image titled Fix a Javascript Error in Windows 10 Step 20

    6

    Click Repair. This performs a few repair steps to the C++ libraries.

    • If prompted, enter your administrator password to confirm.
  7. Image titled Fix a Javascript Error in Windows 10 Step 21

    7

    Try running the installer again. This should resolve most JavaScript installation errors with Microsoft Teams on Windows 10.

  8. Advertisement

  1. Image titled Fix a Javascript Error in Windows 10 Step 22

    1

    Close Discord (or the app you’re trying to fix). If you get a JavaScript error when trying to start Discord or another app, certain processes may be failing because they need more permissions. If the app is running right now, you’ll want to close it. Make sure it’s not minimized to your taskbar.

    • To be sure it’s closed, press Control + Alt + Delete and click Task Manager. If you see a process for the app running, click to select it, and then click End Task.
  2. Image titled Fix a Javascript Error in Windows 10 Step 23

    2

    Right-click the Discord icon on your desktop or in the Windows menu. A menu will expand.

  3. Image titled Fix a Javascript Error in Windows 10 Step 24

    3

    Click Open file location. If you don’t see this option, you may have to click More first. This takes you to the app’s install location.

  4. Image titled Fix a Javascript Error in Windows 10 Step 25

    4

    Double-click the latest version of Discord. If you’ve run a few Discord updates, you may have several folders beginning with app- and ending with a number. Double-click the one with the most recent version number.

    • If you’re trying to fix a different app, you’ll usually see that app right here in the folder you’ve opened. If not, look around for a file with the app’s name—it may end with «.exe.»
  5. Image titled Fix a Javascript Error in Windows 10 Step 26

    5

    Right-click the app and select Properties. Properties for the selected app will appear.

  6. Image titled Fix a Javascript Error in Windows 10 Step 27

    6

    Click the Compatibility tab. It’s at the top of the window.

  7. Image titled Fix a Javascript Error in Windows 10 Step 28

    7

    Check the box next to «Run this program as an administrator.» This gives the app permission to everything on your PC, which may clear up issues caused by access rights.

  8. Image titled Fix a Javascript Error in Windows 10 Step 29

    8

    Click OK. This saves your changes.

  9. Image titled Fix a Javascript Error in Windows 10 Step 30

    9

    Start Discord or your preferred app normally. Now that you’ve set the app to run as an administrator, starting it by double-clicking its icon on your desktop or in the Windows menu will run it with elevated privileges.

  10. Advertisement

Add New Question

  • Question

    Why am I getting a Javascript error with WordPress?

    Luigi Oppido

    Luigi Oppido is the Owner and Operator of Pleasure Point Computers in Santa Cruz, California. Luigi has over 25 years of experience in general computer repair, data recovery, virus removal, and upgrades. He is also the host of the Computer Man Show! broadcasted on KSQD covering central California for over two years.

    Luigi Oppido

    Computer & Tech Specialist

    Expert Answer

    Check the website on other devices, like another computer or a tablet. If the same error shows up, there’s an issue with the code that needs to be looked at. It also helps to make sure that Java is up-to-date on your computer, since a lot of people don’t even update Java anymore (since it’s updated with the operating system).

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

About This Article

Article SummaryX

1. Unblock the installer in your antivirus software.
2. Try deleting the app’s folders in AppData and LocalAppData and then reinstalling.
3. Repair the latest version of Microsoft Visual C++ in Apps & Features.
4. Run the app as an administrator.

Did this summary help you?

Thanks to all authors for creating a page that has been read 37,984 times.

Is this article up to date?

Опубликовано: среда, 29 марта 2023 г. в 09:06

  • JavaScript

В этом руководстве мы погрузимся в обработку ошибок JavaScript, чтобы вы могли выбрасывать исключения, обнаруживать и обрабатывать собственные ошибки.

Опытные разработчики ожидают неожиданного. Если что-то может пойти не так, так оно и будет — обычно в тот момент, когда первый пользователь получает доступ к вашему новому приложению.

Некоторых ошибок веб-приложений можно избежать, например:

  • Хороший редактор или линтер может отлавливать синтаксические ошибки.
  • Хорошая валидация может выявить ошибки пользовательского ввода.
  • Надёжные процессы тестирования могут обнаруживать логические ошибки.

И всё же ошибки остаются. Браузеры могут сбоить или не поддерживать API, который мы используем. Серверы могут дать сбой или слишком долго отвечать. Сетевое соединение может выйти из строя или стать ненадёжным. Проблемы могут быть временными, но мы не может программировать такие проблемы. Однако мы можем предвидеть проблемы, принимать меры по их устранению и повышать отказоустойчивость нашего приложения.

Отображение сообщения об ошибке — крайняя мера

В идеале пользователи никогда не должны видеть сообщения об ошибке.

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

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

Как JavaScript обрабатывает ошибки

Когда оператор JavaScript приводит к ошибке, говорят, что он генерирует (выбрасывает) исключение. JavaScript создаёт и выбрасывает объект Error, описывающий ошибку. Мы можем увидеть это в действии на CodePen. Если установить в десятичные разряды (decimal places) отрицательное число, мы увидим сообщение об ошибке в консоли внизу. (Обратите внимание, что мы не встраиваем CodePen в это руководство, потому что нужно иметь возможно видеть вывод консоли, чтобы этот пример имел смысл)

Результат не обновиться, и мы увидим сообщение RangeError в консоли. Следующая функция выдаёт ошибку, когда dp имеет отрицательно значение:

// division calculation
function divide(v1, v2, dp) {

return (v1 / v2).toFixed(dp);

}

После выдачи ошибки интерпретатор JavaScript проверяет наличие кода обработки исключений. В функции Division() ничего нет, поэтому она проверяет вызывающую функцию:

// show result of division
function showResult() {

result.value = divide(
parseFloat(num1.value),
parseFloat(num2.value),
parseFloat(dp.value)
);

}

Интерпретатор повторяет процесс для каждой функции в стеке вызовов, пока не произойдёт одно из следующих событий:

  • Он находит обработчик исключений.
  • Он достигает верхнего уровня кода (что приводит к завершению программы и отображению ошибки в консоли, как показано в примере на CodePen выше).

Перехват исключений

Мы можем добавить обработчик исключений в функцию divide() с помощью блока try...catch:

// division calculation
function divide(v1, v2, dp) {
try {
return (v1 / v2).toFixed(dp);
}
catch(e) {
console.log(`
error name :
${ e.name }
error message:
${ e.message }
`
);
return 'ERROR';
}
}

Функция выполняет код в блоке try {}, но при возникновении исключения выполняется блок catch {} и получает выброшенный объект ошибки. Как и прежде, попробуйте в decimal places установить отрицательное число в этой демонстрации CodePen.

Теперь result показывает ERROR. Консоль показывает имя ошибки и сообщение, но это выводится оператором console.log и не завершает работу программы.

Примечание: эта демонстрация блока try...catch излишняя для базовой функции, такой как divide(). Как мы увидим ниже, проще убедиться, что dp равен нулю или больше.

Можно определить не обязательный блок finally {}, если требуется, чтобы код запускался при выполнении кода try или catch:

function divide(v1, v2, dp) {
try {
return (v1 / v2).toFixed(dp);
}
catch(e) {
return 'ERROR';
}
finally {
console.log('done');
}
}

В консоль выведется done, независимо от того, успешно ли выполнено вычисление или возникла ошибка. Блок finally обычно выполняет действия, которые в противном случае нам пришлось бы повторять как в блоке try, так и в блоке catch. Например, отмену вызова API или закрытие соединения с базой данных.

Для блока try требуется либо блок catch, либо блок finally, либо и то и другое. Обратите внимание, что когда блок finally содержит оператор return, это значение становится возвращаемым значением для всей функции; другие операторы в блоках try или catch игнорируются.

Вложенные обработчики исключений

Что произойдёт, если мы добавим обработчик исключений к вызывающей функции showResult()?

// show result of division
function showResult() {

try {
result.value = divide(
parseFloat(num1.value),
parseFloat(num2.value),
parseFloat(dp.value)
);
}
catch(e) {
result.value = 'FAIL!';
}

}

Ответ… ничего! Блок catch никогда не выполняется, потому что в функции divide() блок catch обрабатывает ошибку.

Тем не менее мы могли бы программно генерировать новый объект Error в divide() и при желании передать исходную ошибку в свойстве cause второго аргумента:

function divide(v1, v2, dp) {
try {
return (v1 / v2).toFixed(dp);
}
catch(e) {
throw new Error('ERROR', { cause: e });
}
}

Это вызовет блок catch в вызывающей функции:

// show result of division
function showResult() {

try {
//...
}
catch(e) {
console.log( e.message ); // ERROR
console.log( e.cause.name ); // RangeError
result.value = 'FAIL!';
}
}

Стандартные типы ошибок JavaScript

Когда возникает исключение, JavaScript создаёт и выдаёт объект, описывающий ошибку, используя один из следующих типов.

SyntaxError

Ошибка, возникающая из-за синтаксически недопустимого кода, такого как отсутствующая скобка:

if condition) { // SyntaxError
console.log('condition is true');
}

Примечание: такие языки, как C++ и Java, сообщают об ошибках синтаксиса во время компиляции. JavaScript — интерпретируемый язык, поэтому синтаксические ошибки не выявляются до тех пор, пока код не запустится. Любой хороший редактор кода или линтер могут обнаружить синтаксические ошибки до того, как мы попытаемся запустить код.

ReferenceError

Ошибка при доступе к несуществующей переменной:

function inc() {
value++; // ReferenceError
}

Опять, хороший редактор кода или линтер могут обнаружить эту проблему.

TypeError

Ошибка возникает, когда значение не соответствует ожидаемому типу, например, при вызове несуществующего метода объекта:

const obj = {};
obj.missingMethod(); // TypeError

RangeError

Ошибка возникает, когда значение не входит в набор или диапазон допустимых значений. Используемый выше метод toFixed() генерирует эту ошибку, потому что он ожидает значение от 0 до 100:

const n = 123.456;
console.log( n.toFixed(-1) ); // RangeError

URIError

Ошибка выдаваемая функциями обработки URI, такими как encodeURI() и decodeURI(), при обнаружении неправильных URI:

const u = decodeURIComponent('%'); // URIError

EvalError

Ошибка возникающая при передаче строки, содержащей не валидный JavaScript код, в функцию eval():

eval('console.logg x;'); // EvalError

Примечание: пожалуйста, не используйте eval()! Выполнение произвольного кода, содержащегося в строке, возможно, созданной на основе пользовательского ввода, слишком опасно!

AggregateError

Ошибка возникает, когда несколько ошибок объединены в одну ошибку. Обычно возникает при вызове такой операции, как Promise.all(), которая возвращает результаты нескольких промисов.

InternalError

Нестандартная ошибка (только в Firefox) возникает при возникновении внутренней ошибки движка JavaScript. Обычно это результат того, что что-то занимает слишком много памяти, например, большой массив или слишком много рекурсии.

Error

Наконец, есть общий объект Error, чаще всего используемый при реализации собственных исключений… о котором мы поговорим дальше.

Генерация/выбрасывание собственных исключений

Мы можем использовать throw для генерации/выбрасывания собственных исключений, когда возникает ошибка — или должна произойти. Например:

  • нашей функции не передаются валидные параметры
  • ajax-запрос не возвращает ожидаемые данные
  • обновление DOM завершается ошибкой, поскольку узел не существует

Оператор throw фактически принимает любое значение или объект. Например:

throw 'A simple error string';
throw 42;
throw true;
throw { message: 'An error', name: 'MyError' };

Исключения генерируются для каждой функции в стеке вызовов до тех пор, пока они не будут перехвачены обработчиком исключений (catch). Однако на практике мы хотим создать и сгенерировать объект Error, чтобы он действовал идентично стандартным ошибкам, выдаваемым JavaScript.

Можно создать общий объект Error, передав необязательное сообщение конструктору:

throw new Error('An error has occurred');

Так же Error можно использовать как функцию, без new. Она возвращает объект Error, идентичный приведённому выше:

throw Error('An error has occurred');

При желании можно передать имя файла и номер строки в качестве второго и третьего параметров:

throw new Error('An error has occurred', 'script.js', 99);

В этом редко возникает необходимость, так как по умолчанию они относятся к файлу и строке, где мы вызвали объект Error. (Также их сложно поддерживать, поскольку наши файлы меняются!)

Мы можем определить общие объекты Error, но по возможности следует использовать стандартный тип Error. Например:

throw new RangeError('Decimal places must be 0 or greater');

Все объекты Error имеют следующие свойства, которые можно проверить в блоке catch:

  • .name: имя типа ошибки, например Error или RangeError.
  • .message: сообщение об ошибке.

В Firefox поддерживаются следующие нестандартные свойства:

  • .fileName: файл, в котором произошла ошибка.
  • .lineNumber: номер строки, в которой произошла ошибка.
  • .columnNumber: номер столбца, в котором произошла ошибка.
  • .stack: трассировка стека со списком вызовов функций, сделанных до возникновения ошибки.

Мы можем изменить функцию divide() так, чтобы она вызывала ошибку RangeError, когда количество знаков после запятой не является числом, меньше нуля и больше восьми:

// division calculation
function divide(v1, v2, dp) {

if (isNaN(dp) || dp < 0 || dp > 8) {
throw new RangeError('Decimal places must be between 0 and 8');
}

return (v1 / v2).toFixed(dp);
}

Точно так же мы могли бы выдать Error или TypeError, когда значения делимого не является числом, чтобы предотвратить результат NaN:

  if (isNaN(v1)) {
throw new TypeError('Dividend must be a number');
}

Также можно обрабатывать делитель, который не является числом или равен нулю. JavaScript возвращает Infinity при делении на ноль, но это может запутать пользователя. Вместо того чтобы вызывать общую ошибку, мы могли бы создать собственный тип ошибки DivByZeroError:

// new DivByZeroError Error type
class DivByZeroError extends Error {
constructor(message) {
super(message);
this.name = 'DivByZeroError';
}
}

Затем вызывать/выбрасывать его подобным образом:

if (isNaN(v2) || !v2) {
throw new DivByZeroError('Divisor must be a non-zero number');
}

Теперь добавьте блок try...catch к вызывающей функции showResult(). Он сможет получить тип любой ошибки и отреагировать соответствующим образом — в данном случае, выводя сообщение об ошибке:

// show result of division
function showResult() {

try {
result.value = divide(
parseFloat(num1.value),
parseFloat(num2.value),
parseFloat(dp.value)
);
errmsg.textContent = '';
}
catch (e) {
result.value = 'ERROR';
errmsg.textContent = e.message;
console.log( e.name );
}

}

Попробуйте ввести недопустимые нечисловые, нулевые и отрицательные значения в демонстрации на CodePen.

Окончательная версия функции divide() проверяет все входящие значения и при необходимости выдаёт соответствующую ошибку:

// division calculation
function divide(v1, v2, dp) {

if (isNaN(v1)) {
throw new TypeError('Dividend must be a number');
}

if (isNaN(v2) || !v2) {
throw new DivByZeroError('Divisor must be a non-zero number');
}

if (isNaN(dp) || dp < 0 || dp > 8) {
throw new RangeError('Decimal places must be between 0 and 8');
}

return (v1 / v2).toFixed(dp);
}

Больше нет необходимости размещать блок try...catch вокруг финального return, так как он никогда не должен генерировать ошибку. Если бы это произошло, JavaScript сгенерировал бы свою собственную ошибку и обработал бы её блоком catch в showResult()/

Ошибки асинхронной функции

Мы не можем перехватывать исключения, генерируемые асинхронными функциями на основе обратного вызова, потому что после завершения выполнения блока try...catch выдаётся ошибка. Этот код выглядит правильно, но блок catch никогда не выполнится, и через секунду консоль отобразит сообщение Uncaught Error:

function asyncError(delay = 1000) {

setTimeout(() => {
throw new Error('I am never caught!');
}, delay);

}

try {
asyncError();
}
catch(e) {
console.error('This will never run');
}

Соглашение, принятое в большинстве фреймворков и серверных сред выполнения, таких как Node.js, заключается в том, чтобы возвращать ошибку в качестве первого параметра функции обратного вызова. Это не приведёт к возникновению исключения, хотя при необходимости мы можем вручную сгенерировать ошибку:

function asyncError(delay = 1000, callback) {

setTimeout(() => {
callback('This is an error message');
}, delay);

}

asyncError(1000, e => {

if (e) {
throw new Error(`error: ${ e }`);
}

});

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

Обратные вызовы могут стать громоздкими, поэтому при написании асинхронного кода предпочтительнее использовать промисы. При возникновении ошибки метод reject() промиса может вернуть новый объект Error или любое другое значение:

function wait(delay = 1000) {

return new Promise((resolve, reject) => {

if (isNaN(delay) || delay < 0) {
reject( new TypeError('Invalid delay') );
}
else {
setTimeout(() => {
resolve(`waited ${ delay } ms`);
}, delay);
}

})

}

Примечание: функции должны быть либо 100% синхронными, либо 100% асинхронными. Вот почему необходимо проверять значение delay внутри возвращаемого промиса. Если бы мы проверили значение delay и выдали ошибку перед возвратом промиса, функция стала бы синхронной при возникновении ошибки.

Метод Promise.catch() выполняется при передаче недопустимого параметра delay и получает возвращённый объект Error:

// invalid delay value passed
wait('INVALID')
.then( res => console.log( res ))
.catch( e => console.error( e.message ) )
.finally( () => console.log('complete') );

Я считаю цепочки промисов немного сложными для чтения. К счастью, мы можем использовать await для вызова любой функции, возвращающей промис. Это должно происходить внутри асинхронной функции, но мы можем перехватывать ошибки с помощью стандартного блока try...catch.

Следующая (вызываемая немедленно) асинхронная функция функционально идентична цепочке промисов выше:

(async () => {

try {
console.log( await wait('INVALID') );
}
catch (e) {
console.error( e.message );
}
finally {
console.log('complete');
}

})();

Исключительная обработка исключения

Выбрасывать объекты Error и обрабатывать исключения в JavaScript легко:

try {
throw new Error('I am an error!');
}
catch (e) {
console.log(`error ${ e.message }`)
}

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

Дополнительная информация:

  • MDN Порядок выполнения и обработка ошибок
  • MDN try…catch
  • MDN Error

09.03.2020

Просмотров: 70859

На компьютере с Windows 7, 8 и 10 при запуске программы Skype, Faceit и Discord может появиться ошибка JavaScript error occurred in the main process, которая свидетельствует о повреждении системных файлов, отключении нужной службы или о необходимости применения прав Администратора. Решение данной ошибки достаточно простое. Однако для каждой программы будут отличаться некоторые рекомендации.

Читайте также: Как исправить ошибку 0xc0000906 на Windows 7 при запуске игр и приложений?

Методы решения ошибки JavaScript error occurred in the main process

Если при запуске программы Skype, Faceit и Discord на вашем ПК возникла ошибка JavaScript error occurred in the main process, то в первую очередь нужно снять задачу в Диспетчере задач. Для этого нужно нажать на Панели задач провой кнопкой мыши и выбрать «Запустить Диспетчер задач».

Далее переходим во вкладку «Процессы» и завершаем процессы, которые связаны с программой, при запуске которой вылетает ошибка.

После того, как задачи к приложениям были сняты, нужно очистить папки программ с кэшем. Для этого нужно нажать «Win+R», чтобы вызвать окно «Выполнить» и ввести %appdata%.

Находим папку программы, при запуске которой возникает ошибка JavaScript error occurred in the main process и удаляем её.

 

Теперь в окне «Выполнить» необходимо ввести %localappdata% и также найти и удалить директорию, принадлежащую сбойной программе. После этого перезагружаем систему. Программа сама создаст нужные папки.

В случае, если после удаления данных папок ошибка не исчезла, рекомендуем полностью удалить программу и установить её заново, только с применением прав Администратора. Для этого нужно нажать на ярлыке софта правой кнопкой мыши и вызвать «Свойства». Далее переходим во вкладку «Совместимость» и ставим галочку «Выполнить запуск от имени Администратора».

В случае, если такая ошибка возникала в программе Skype, то проблема может крыться в отсутствии браузера Internet Explorer, который нужен для нормальной работы некоторых функций Windows. В данном случае рекомендуем выполнить следующие действия:

  • Открываем «Проводник», нажимаем на кнопке «Удалить или изменить программу».

  • Появиться окно с установленными программами. В меню слева выбираем «Включение или отключение компонентов Windows».

  • Появиться небольшое окно. Нужно найти браузер Internet Explorer. Возле него должна стоять отметка. Смотрим также версию программы. Для нормальной работы Скайпа нужен Internet Explorer 11.

  • Если у вас версия браузера ниже, то нужно обновить операционную систему, включив ту версию браузера, которая есть. Если же вы обновили Windows, но версия браузера не изменилась, то можно перейти на официальный сайт Майкрософт и скачать Internet Explorer 11. Обращаем внимание на разрядность программы. Нужно скачать софт в соответствии с разрядностью своей Windows.
  • Устанавливаем программу, обязательно обновляем сам Скайп.

Если ошибка и после данных манипуляций не была исправлена, то пробуем перерегистрировать файл dll. Для этого советуем открыть командную строку с правами Администратора и ввести regsvr32 jscript.dll.

Перезагружаем систему, чтобы изменения вступили в силу и проверяем, исправлена ли ошибка.

Также на зарубежных форумах пользователи указывали, что ошибка A JavaScript error occurred in the main process появлялась по причине неверной работы службы Quality Windows Audio Video Experience. Исправить неполадку удалось путем изменения типа запуска службы с ручного на автоматический. Для этого нужно нажать «Win+R» и ввести «services.msc». Находим службу.

Двойным кликом открываем окно службы и меняем тип запуска.

Перезагружаем систему и проверяем, появляется ли ошибка или нет.

Если исправить ошибку A JavaScript error occurred in the main process вышеуказанными способами не удалось, рекомендуем проверить систему на вирусы и выполнить восстановление системы с помощью контрольной точки или установочного диска.

Ошибки в JavaScript и как их исправить

original

JavaScript может быть кошмаром при отладке: некоторые ошибки, которые он выдает, могут быть очень трудны для понимания с первого взгляда, и выдаваемые номера строк также не всегда полезны. Разве не было бы полезно иметь список, глядя на который, можно понять смысл ошибок и как исправить их? Вот он!

Ниже представлен список странных ошибок в JavaScript. Разные браузеры могут выдавать разные сообщения об одинаковых ошибках, поэтому приведено несколько примеров там, где возможно.

Как читать ошибки?

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

Типичная ошибка из Chrome выглядит так:

Uncaught TypeError: undefined is not a function

Структура ошибки следующая:

  1. Uncaught TypeError: эта часть сообщения обычно не особо полезна. Uncaught значит, что ошибка не была перехвачена в catch, а TypeError — это название ошибки.

  2. undefined is not a function: это та самая часть про ошибку. В случае с сообщениями об ошибках, читать их нужно прямо буквально. Например, в этом случае, она значит то, что код попытался использовать значение undefined как функцию.

Другие webkit-браузеры, такие как Safari, выдают ошибки примерно в таком же формате, как и Chrome. Ошибки из Firefox похожи, но не всегда включают в себя первую часть, и последние версии Internet Explorer также выдают более простые ошибки, но в этом случае проще — не всегда значит лучше.

Теперь к самим ошибкам.

Uncaught TypeError: undefined is not a function

Связанные ошибки: number is not a function, object is not a function, string is not a function, Unhandled Error: ‘foo’ is not a function, Function Expected

Возникает при попытке вызова значения как функции, когда значение функцией не является. Например:

var foo = undefined;
foo();

Эта ошибка обычно возникает, если вы пытаетесь вызвать функцию для объекта, но опечатались в названии.

var x = document.getElementByID('foo');

Несуществующие свойства объекта по-умолчанию имеют значение undefined, что приводит к этой ошибке.

Другие вариации, такие как “number is not a function” возникают при попытке вызвать число, как будто оно является функцией.

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

Uncaught ReferenceError: Invalid left-hand side in assignment

Связанные ошибки: Uncaught exception: ReferenceError: Cannot assign to ‘functionCall()’, Uncaught exception: ReferenceError: Cannot assign to ‘this’

Вызвано попыткой присвоить значение тому, чему невозможно присвоить значение.

Наиболее частый пример этой ошибки — это условие в if:

if(doSomething() = 'somevalue')

В этом примере программист случайно использовал один знак равенства вместо двух. Выражение “left-hand side in assignment” относится к левой части знака равенства, а, как можно видеть в данном примере, левая часть содержит что-то, чему нельзя присвоить значение, что и приводит к ошибке.

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

Uncaught TypeError: Converting circular structure to JSON

Связанные ошибки: Uncaught exception: TypeError: JSON.stringify: Not an acyclic Object, TypeError: cyclic object value, Circular reference in value argument not supported

Всегда вызвано циклической ссылкой в объекте, которая потом передается в JSON.stringify.

var a = { };
var b = { a: a };
a.b = b;
JSON.stringify(a);

Так как a и b в примере выше имеют ссылки друг на друга, результирующий объект не может быть приведен к JSON.

Как исправить ошибку: удалите циклические ссылки, как в примере выше, из всех объектов, которые вы хотите сконвертировать в JSON.

Unexpected token ;

Связанные ошибки: Expected ), missing ) after argument list

Интерпретатор JavaScript что-то ожидал, но не обнаружил там этого. Обычно вызвано пропущенными фигурными, круглыми или квадратными скобками.

Токен в данной ошибке может быть разным — может быть написано “Unexpected token ]”, “Expected {” или что-то еще.

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

Ошибка с [ ] { } ( ) обычно вызвано несовпадающей парой. Проверьте, все ли ваши скобки имеют закрывающую пару. В этом случае, номер строки обычно указывает на что-то другое, а не на проблемный символ.

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

Unexpected ; обычно вызвано символом ; внутри литерала объекта или массива, или списка аргументов вызова функции. Номер строки обычно также будет верным для данного случая.

Uncaught SyntaxError: Unexpected token ILLEGAL

Связанные ошибки: Unterminated String Literal, Invalid Line Terminator

В строковом литерале пропущена закрывающая кавычка.

Как исправить ошибку: убедитесь, что все строки имеют правильные закрывающие кавычки.

Uncaught TypeError: Cannot read property ‘foo’ of null, Uncaught TypeError: Cannot read property ‘foo’ of undefined

Связанные ошибки: TypeError: someVal is null, Unable to get property ‘foo’ of undefined or null reference

Попытка прочитать null или undefined так, как будто это объект. Например:

var someVal = null;
console.log(someVal.foo);

Как исправить ошибку: обычно вызвано опечатками. Проверьте, все ли переменные, использованные рядом со строкой, указывающей на ошибку, правильно названы.

Uncaught TypeError: Cannot set property ‘foo’ of null, Uncaught TypeError: Cannot set property ‘foo’ of undefined

Связанные ошибки: TypeError: someVal is undefined, Unable to set property ‘foo’ of undefined or null reference

Попытка записать null или undefined так, как будто это объект. Например:

var someVal = null;
someVal.foo = 1;

Как исправить ошибку: это тоже обычно вызвано ошибками. Проверьте имена переменных рядом со строкой, указывающей на ошибку.

Uncaught RangeError: Maximum call stack size exceeded

Связанные ошибки: Uncaught exception: RangeError: Maximum recursion depth exceeded, too much recursion, Stack overflow

Обычно вызвано неправильно программной логикой, что приводит к бесконечному вызову рекурсивной функции.

Как исправить ошибку: проверьте рекурсивные функции на ошибки, которые могут вынудить их делать рекурсивные вызовы вечно.

Uncaught URIError: URI malformed

Связанные ошибки: URIError: malformed URI sequence

Вызвано некорректным вызовом decodeURIComponent.

Как исправить ошибку: убедитесь, что вызовы decodeURIComponent на строке ошибки получают корректные входные данные.

XMLHttpRequest cannot load http://some/url/. No ‘Access-Control-Allow-Origin’ header is present on the requested resource

Связанные ошибки: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://some/url/

Эта проблема всегда связана с использованием XMLHttpRequest.

Как исправить ошибку: убедитесь в корректности запрашиваемого URL и в том, что он удовлетворяет same-origin policy. Хороший способ найти проблемный код — посмотреть на URL в сообщении ошибки и найти его в своём коде.

InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

Связанные ошибки: InvalidStateError, DOMException code 11

Означает то, что код вызвал функцию, которую нельзя было вызывать в текущем состоянии. Обычно связано c XMLHttpRequest при попытке вызвать на нём функции до его готовности.

var xhr = new XMLHttpRequest();
xhr.setRequestHeader('Some-Header', 'val');

В данном случае вы получите ошибку потому, что функция setRequestHeader может быть вызвана только после вызова xhr.open.

Как исправить ошибку: посмотрите на код в строке, указывающей на ошибку, и убедитесь, что он вызывается в правильный момент или добавляет нужные вызовы до этого (как с xhr.open).

Заключение

JavaScript содержит в себе одни из самых бесполезных ошибок, которые я когда-либо видел, за исключением печально известной Expected T_PAAMAYIM_NEKUDOTAYIM в PHP. Большая ознакомленность с ошибками привносит больше ясности. Современные браузеры тоже помогают, так как больше не выдают абсолютно бесполезные ошибки, как это было раньше.

Какие самые непонятные ошибки вы встречали? Делитесь своими наблюдениями в комментариях.

Понравилась статья? Поделить с друзьями:
  • Java синтаксическая ошибка в имени файла
  • Java пишет ошибку java lang nullpointerexception
  • Java virtual machine launcher unable to access jarfile ошибка
  • Java swing сообщение об ошибке
  • Java platform se binary как исправить ошибку