Главная » Error » Ошибки при работе с переменными

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

В этой статье

Задание

Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение ‘Dragon’;

После выполнения программы результат на экране должен выглядеть так:

Targaryen
and
Dragon
Упражнение не проходит проверку — что делать?

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

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

В моей среде код работает, а здесь нет

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя

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

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

Прочитал урок — ничего не понятно

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

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

Встроенные ошибки

Секция статьи “Встроенные ошибки”

SyntaxError

Секция статьи “SyntaxError”

Чаще всего встречаются опечатки — неправильные названия методов, лишние или отсутствующие точки с запятой или скобочки и так далее. Такой тип ошибок называется «синтаксическим», SyntaxError:

console.log(;)// SyntaxError: Unexpected token ‘;’console.log(()// SyntaxError: missing ) after argument listconsole.log(;)// SyntaxError: Unexpected token ‘;’console.log(()// SyntaxError: missing ) after argument listСкопироватьСкопированоНе удалось скопировать

ReferenceError

Секция статьи “ReferenceError”

Если попытаться обратиться к несуществующей переменной, произойдёт ошибка ReferenceError:

console.log(name)// ReferenceError: name is not definedconsole.log(name)// ReferenceError: name is not definedСкопироватьСкопированоНе удалось скопировать

TypeError

Секция статьи “TypeError”

Если попытаться обратиться к несуществующему свойству, произойдёт ошибка TypeError:

console.log(null.length)// TypeError: Cannot read property ‘length’ of nullundefined()// TypeError: undefined is not a functionconsole.log(null.length)// TypeError: Cannot read property ‘length’ of nullundefined()// TypeError: undefined is not a functionСкопироватьСкопированоНе удалось скопировать

RangeError

Секция статьи “RangeError”

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

new Array(10000000000)// RangeError: Недопустимая длина массиваnewArray(10000000000)// RangeError: Недопустимая длина массиваСкопироватьСкопированоНе удалось скопировать

URIError

Секция статьи “URIError”

Этот тип ошибок возникает при неправильном использовании обработки URI.

decodeURIComponent(‘%’)// URIError: URI malformeddecodeURIComponent(‘%’)// URIError: URI malformedСкопироватьСкопированоНе удалось скопировать

Валидным считается URI, формат которого соответствует спецификации RFC 3986:

URI = scheme:[//authority]path[?query][#fragment]

EvalError

Секция статьи “EvalError”

EvalError представляет ошибку, возникающую в глобальной функции eval().

eval( ‘console.log(null.length)’)eval(‘console.log(null.length)’)СкопироватьСкопированоНе удалось скопировать

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

InternalError (не стандарт)

Секция статьи “InternalError (не стандарт)”

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

“InternalError: инициализатор массива слишком большой”.

Бросаем исключения на примере

Мы рассмотрели теорию, а теперь давайте изучим пример:

function doAthing() {
byDoingSomethingElse();
}

function byDoingSomethingElse() {
throw new Error(‘Uh oh!’);
}

function init() {
try {
doAthing();
} catch(e) {
console.log(e);
// [Error: Uh oh!] }
}

init();

Здесь в функции инициализации init() предусмотрена обработка ошибок, поскольку она содержит try/catch блок.

init() вызывает функцию doAthing(), которая вызывает функцию byDoingSomethingElse(), где выбрасывается исключение. Именно в этот момент ошибки, программа останавливается и начинает отслеживать функцию, вызвавшую ошибку. Далее в функции init() и выполняет операторcatch. С помощью оператора catch мы решаем что делать: подавить ошибку или даже выдать другую ошибку (для распространения вверх).

Стек вызовов

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

Но как работает стек вызовов?

Всякий раз, когда вызывается функция, она помещается в стек, а при завершении удаляется из стека. Именно от этого стека мы получили название «трассировки стека».

Трассировка стека – это список функций, которые были вызваны до момента, когда в программе произошло исключение.

Она часто выглядит так:

Error: Uh oh!
at byDoingSomethingElse (/filesystem/aProgram.js:7:11)
at doAthing (/filesystem/aProgram.js:3:5)
at init (/filesystem/aProgram.js:12:9)
at Object. (/filesystem/aProgram.js:19:1)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)

На этом этапе вам может быть интересно, как стек вызовов помогает нам с обработкой ошибок Node.js. Давайте поговорим о важности стеков вызовов.

Стек вызовов предоставляет «хлебные крошки», помогая проследить путь, который привел к исключению(ошибке).

Почему у нас должны быть функции без имен? Иногда в наших программах мы хотим определить маленькие одноразовые функции, которые выполняют небольшую задачу. Мы не хотим утруждать себя задачей давать им имена, но именно эти анонимные функции могут вызвать у нас всевозможные головные боли. Анонимная функция удаляет имя функции из нашего стека вызовов, что делает наш стек вызовов значительно более сложным в использовании.

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

Как исправить 405 Method Not Allowed?

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

Что может сделать пользователь?

Ошибка Method Not Allowed под номером 4хх вроде бы говорит о вине клиента. Но несмотря на это, пользователь мало что может сделать, чтобы устранить проблему. В его компетенции только убедиться в том, что он не допустил ошибку в базовых вещах, и попробовать повторить те же действия в надежде на успех.

Заново открыть ту же страницу

Иногда 405 Method Not Allowed может исчезнуть после перезагрузки страницы. Так что перед тем как принимать сложные решения и жаловаться на владельцев сайта, нажмите F5 или Cmd + R раза два. 

Проверить, правильно ли он ввел URL-адрес

Несложная задача, но полезная. Как и в случае с кучей других ошибок, 405 может явиться из-за банальной опечатки или лишнего символа. К тому же многие серверы защищены таким образом, чтобы напрочь блокировать доступ к несуществующим страницам или каким-либо подуровням (в которые человек может пытаться залезть неслучайно). 

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

Что может сделать владелец сайта?

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

Проверить настройки сервера

Тут будут инструкции для владельцев сайтов на базе Apache и Nginx в Timeweb. Понятно, что есть другие варианты конфигураций, но эти два — чуть ли стандарт, использующийся повсеместно. А информация, касающаяся конкретно Timeweb, заденет только расположение файлов и работу с панелью управления хостинга. Остальные моменты универсальны. 

Исправить проблемы, связанные с PHP-скриптами

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

Обойти ограничение можно тремя путями:

  • Попробовать экспортировать БД через phpMyAdmin.
  • Разбить файл БД на несколько мелких частей, передача каждого из которых займет меньше 30 секунд.
  • Использовать для передачи БД Cron-задачу. На них сервер выделяет больше времени.

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

Исправить эксклюзивные для Nginx ошибки

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

Первый вариант — убедить сервер в том, что вместо кода 405 надо отправлять код 200, и это вполне нормально:

server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm; }
error_page 404 /404.html;
error_page 403 /403.html;
error_page 405 =200 $uri;…}

Для тех, у кого Nginx-сервер — это proxy, понадобится вот такой код:

error_page 405 =200 @405; location @405 { root /htdocs; proxy_pass http://localhost:8080; }

Аналогичная ошибка возникает при работе с модулем FastCGI. Из-за него сервер неправильно считывает запросы с методом POST, поэтому необходимо делить параметры и адрес скрипта вот так:

location ~.php(.*) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+.php)(.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include /etc/nginx/fastcgi_params;
}

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

Проанализировать все недавние изменения в коде

Если недавно что-то поменяли, а после этого все сломалось, то надо это «поменяли» рассмотреть подробнее. Провести ручной дебаггинг, если можно это так назвать. Наверняка где-то затесалась несерьезная, но обидная ошибка. 

Удалить сторонние дополнения для CMS

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

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

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

Главное, не забудьте сделать резервную копию CMS перед тем, как что-то удалять и менять. И продолжайте делать бэкапы после, чтобы всегда можно было восстановить рабочую версию сайта.

Откатиться на более старую версию CMS

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

Оператор try…catch…finally

Оператор try-catch также может содержать предложение finally. Код внутри блока finally всегда будет выполняться независимо от того, произошла ошибка в блоке try или нет.

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

// Присвоение значения, возвращаемого диалоговым окном
var num = prompt(“Enter a positive integer between 0 to 100”);

// Запоминание времени начала исполнения
var start = Date.now();

try {
if(num > 0 && num <= 100) { alert(Math.pow(num, num)); // the base to the exponent power } else { throw new Error("An invalid value is entered!"); } } catch(e) { alert(e.message); } finally { // Отображение времени, необходимого для выполнения кода alert("Execution took: " + (Date.now() - start) + "ms"); }

Решение проблемы

Для устранения ошибки, откройте корневую директорию мессенджера. Найдите директории с названием «AppData» и «AppDataLocal». Из-за стандартных настроек ОС они могут быть недоступны для просмотра. Чтобы получить доступ к данным папкам, сделайте следующее:

  1. Зайдите в меню «Пуск» или воспользуйтесь комбинацией горячих клавиш «Win+R».
  2. Нажмите на «Выполнить».

    Окно «Выполнить»

  3. В появившемся окошке следует вписать команды «%localappdata%» и «%appdata%», которые откроют доступ к скрытым директориям.
  4. Удалите абсолютно все файлы в этих папках, в названии которых встречается «Discord».
  5. Из мессенджера также необходимо выйти. Самый действенный способ – принудительно отключить все процессы через «Диспетчер задач».
  6. Удалите мессенджер, а потом установите программу заново.

Этих действий достаточно для решения проблемы и восстановления корректной работы программного обеспечения.

Окончательное заявление

Оператор 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: ” +

Значения имени ошибки

В свойстве “имя ошибки” может быть возвращено шесть различных значений:

ОшибкиОписание
EvalErrorAn error occurred in the eval () function
RangeErrorЧисло “вне диапазона” произошло
ReferenceErrorПроизошла незаконная ссылка
SyntaxErrorПроизошла синтаксическая ошибка
TypeErrorПроизошла ошибка типа
URIErrorПроизошла ошибка в encodeURI ()

Шесть различных значений описаны ниже.

JavaScript бросает ошибки

При возникновении ошибки JavaScript обычно останавливается и генерирует сообщение об ошибке.

Технический термин для этого: JavaScript будет генерировать исключение (выбросить ошибку).

JavaScript фактически создаст объект Error с двумя свойствами: Name и Message.

Отлавливать или не отлавливать?

На данном этапе стоит спросить себя, повсеместно ли добавляется .catch к промисам, поскольку это опционально. Из-за проблем с сетью, аппаратного сбоя или истекшего времени ожидания в асинхронных вызовах возникает исключение. По этим причинам указывайте программе, что делать в случаях невыполнения промиса.

Запомните «Золотое правило» – каждый раз обрабатывать исключения в обещаниях.

JavaScript попробовать и поймать

Инструкция try позволяет определить блок кода для проверки на наличие ошибок во время его выполнения.

Инструкция catch позволяет определить блок кода, который будет выполняться, если в блоке try возникает ошибка.

Операторы JavaScript try и catch поставляются парами:

try {
    Block of code to try
}
catch(err) {
    Block of code to handle errors
}

Мы разберемся с этой ошибкой, обещаю!

Давайте взглянем на анатомию обещаний.

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

Но что все это значит для обработки ошибок Node.js?

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

Изучим код ниже:

function getData() {
return Promise.resolve(‘Do some stuff’);
}

function changeDataFormat() {
// …
}

function storeData(){
// …
}

getData()
.then(changeDataFormat)
.then(storeData)
.catch((e) => {
// Handle the error!
})

Здесь видно, как объединить обработку ошибок для трех различных функций в один обработчик, т. е. код ведет себя так же, как если бы три функции заключались в синхронный блок try/catch.

Ошибка типа

Если используется значение, находящиеся вне диапазона ожидаемых типов, создается TypeError.

Пример

var num = 1;
try {
    num.toUpperCase();   // You cannot convert a number
to upper case
}
catch(err) {
    document.getElementById(“demo”).innerHTML = err.name;
}

Анатомия Объекта Error

Первое, с чего стоит начать изучение – это объект Error.

Разберем на примере:

throw new Error(‘database failed to connect’);

Здесь происходят две вещи: создается объект Error и выбрасывается исключение.

Начнем с рассмотрения объекта Error, и того, как он работает. К ключевому слову throwвернемся чуть позже.

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

Встроенный конструктор ошибок – это общепринятый метод создания объектов ошибок.

Тем не менее, что же такое объекты ошибок? Почему они должны быть однородными? Это важные вопросы, поэтому давайте перейдем к ним.

Первым аргументом для объектаError является его описание.

Описание – это понятная человеку строка объекта ошибки. Также эта строка появляется в консоли, когда что-то пошло не так.

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

class FancyError extends Error {
constructor(args){
super(args);
this.name = “FancyError”
}
}

console.log(new Error(‘A standard error’))
// { [Error: A standard error] }

console.log(new FancyError(‘An augmented error’))
// { [Your fancy error: An augmented error] name: ‘FancyError’ }

Обработка ошибок становится проще, когда у нас есть согласованность в объектах.

Ранее мы упоминали, что хотим, чтобы объекты ошибок были однородными. Это поможет обеспечить согласованность в объекте ошибки.

Теперь давайте поговорим о следующей части головоломки – throw.

Вызов ошибок с помощью оператора throw

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

Общий синтаксис оператора throw: throw expression;

Выражение expression может быть объектом или значением любого типа данных. Однако лучше использовать объекты, желательно со свойствами name и message. Встроенный в JavaScript конструктор Error() предоставляет удобный способ создания объекта ошибки. Давайте посмотрим на некоторые примеры:

throw 123;
throw “Missing values!”;
throw true;
throw { name: “InvalidParameter”, message: “Parameter is not a number!” };
throw new Error(“Something went wrong!”);

Если вы используете встроенные в JavaScript функции конструктора ошибок (например, Error(), TypeError() и т. д.) для создания объектов ошибок, тогда свойство name совпадает с именем конструктора, а message равно аргументу функции конструктора.

Теперь мы собираемся создать функцию squareRoot(), чтобы найти квадратный корень числа. Это можно сделать просто с помощью встроенной в JavaScript функции Math.sqrt() , но проблема здесь в том, что она возвращает NaN для отрицательных чисел, не давая никаких подсказок о том, что пошло не так.

Мы собираемся исправить эту проблему, показывая пользователю ошибку, если указано отрицательное число.

function squareRoot(number) {
// Выдает ошибку, если число отрицательное
if(number < 0) { throw new Error("Sorry, can't calculate square root of a negative number."); } else { return Math.sqrt(number); } } try { squareRoot(16); squareRoot(625); squareRoot(-9); squareRoot(100); // Если выдается ошибка, следующая строка не будет выполнена alert("All calculations are performed successfully."); } catch(e) { // Обработка ошибки alert(e.message); }

Теоретически можно вычислить квадратный корень из отрицательного числа, используя мнимое число i, где i2 = -1. Следовательно, квадратный корень из -4 равен 2i, квадратный корень из -9 равен 3i и так далее. Но мнимые числа не поддерживаются в JavaScript.

Из-за чего я вижу эту ошибку?

Есть 9 HTTP-методов, которые используются браузерами для общения с серверами. Из них два задействуются чаще остальных. Это метод GET для запроса информации с ресурса и метод POST для передачи какой-нибудь информации на ресурс. Два метода покрывают почти все существующие сценарии взаимодействия клиента и сервера от запроса статьи до отправки логина и пароля на сайт. Так как они выполняют разные задачи, для сервера нет никакой нужды принимать GET для авторизации на сайте или POST для загрузки данных. Если же клиент так делает и отправляет некорректный запрос (не с тем методом, который должен быть), то сервер ответит ему ошибкой. То же произойдет, если ресурс будет настроен так, что не сможет принимать специфичный набор запросов, не попадающих в «стандарт». Такие дела.

Задачи

Итого

  • Мы можем наследовать свои классы ошибок от Error и других встроенных классов ошибок, но нужно позаботиться о свойстве name и не забыть вызвать super.
  • Мы можем использовать instanceof для проверки типа ошибок. Это также работает с наследованием. Но иногда у нас объект ошибки, возникшей в сторонней библиотеке, и нет простого способа получить класс. Тогда для проверки типа ошибки можно использовать свойство name.
  • Обёртывание исключений является распространённой техникой: функция ловит низкоуровневые исключения и создаёт одно «высокоуровневое» исключение вместо разных низкоуровневых. Иногда низкоуровневые исключения становятся свойствами этого объекта, как err.cause в примерах выше, но это не обязательно.

Дальнейшее наследование

Класс ValidationError является слишком общим. Много что может пойти не так. Свойство может отсутствовать или иметь неверный формат (например, строка как значение возраста age). Поэтому для отсутствующих свойств сделаем более конкретный класс PropertyRequiredError. Он будет нести дополнительную информацию о свойстве, которое отсутствует.

class ValidationError extends Error {
constructor(message) {
super(message);
this.name = “ValidationError”;
}
}

class PropertyRequiredError extends ValidationError {
constructor(property) {
super(“Нет свойства: ” + property);
this.name = “PropertyRequiredError”;
this.property = property;
}
}

// Применение
function readUser(json) {
let user = JSON.parse(json);

if (!user.age) {
throw new PropertyRequiredError(“age”);
}
if (!user.name) {
throw new PropertyRequiredError(“name”);
}

return user;
}

// Рабочий пример с try..catch

try {
let user = readUser(‘{ “age”: 25 }’);
} catch (err) {
if (err instanceof ValidationError) {
alert(“Неверные данные: ” + err.message); // Неверные данные: Нет свойства: name
alert(err.name); // PropertyRequiredError
alert(err.property); // name
} else if (err instanceof SyntaxError) {
alert(“Ошибка синтаксиса JSON: ” + err.message);
} else {
throw err; // неизвестная ошибка, повторно выбросит исключение
}
}

Новый класс PropertyRequiredError очень просто использовать: необходимо указать только имя свойства new PropertyRequiredError(property). Сообщение для пользователя message генерируется конструктором.

Обратите внимание, что свойство this.name в конструкторе PropertyRequiredError снова присвоено вручную. Правда, немного утомительно – присваивать this.name = в каждом классе пользовательской ошибки. Можно этого избежать, если сделать наш собственный «базовый» класс ошибки, который будет ставить this.name = this.constructor.name. И затем наследовать все ошибки уже от него.

Давайте назовём его MyError.

Вот упрощённый код с MyError и другими пользовательскими классами ошибок:

class MyError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}

class ValidationError extends MyError { }

class PropertyRequiredError extends ValidationError {
constructor(property) {
super(“Нет свойства: ” + property);
this.property = property;
}
}

// name корректное
alert( new PropertyRequiredError(“field”).name ); // PropertyRequiredError

Теперь пользовательские ошибки стали намного короче, особенно ValidationError,
так как мы избавились от строки “this.name = …” в конструкторе.

Ключевое слово Throw

Создание объектов ошибок – это не конец истории, а только подготовка ошибки к отправке. Отправка ошибки заключается в том, чтобы выбросить исключение. Но что значит выбросить? И что это значит для нашей программы?

Throw делает две вещи: останавливает выполнение программы и находит зацепку, которая мешает выполнению программы.

Давайте рассмотрим эти идеи одну за другой:

  • Когда JavaScript находит ключевое слово throw, первое, что он делает – предотвращает запуск любых других функций. Остановка снижает риск возникновения любых дальнейших ошибок и облегчает отладку программ.
  • Когда программа остановлена, JavaScript начнет отслеживать последовательную цепочку функций, которые были вызваны для достижения оператора catch. Такая цепочка называется стек вызовов(англ. call stack). Ближайший catch, который находит JavaScript, является местом, где возникает выброшенное исключение. Если операторы try/catch не найдены, тогда возникает исключение, и процесс Node.js завершиться, что приведет к перезапуску сервера.

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека фронтендера»
Интересно, перейти к каналу

Как это понять

Секция статьи “Как это понять”

Error

Секция статьи “Error”

Общий конструктор ошибок.

new Error(‘Общая ошибка. Проверьте код’)newError(‘Общая ошибка. Проверьте код’)СкопироватьСкопированоНе удалось скопировать

Вызов конструктора возвращает объект ошибки со следующими свойствами:

  • message представляет человекопонятное описание ошибки для встроенных типов (SyntaxError, TypeError и так далее) и переданное в конструктор значение для общего типа Error.
  • name — имя типа (класса) ошибки.

const commonError = new Error(‘Общая ошибка. Проверьте код’)console.log(commonError.message)// ‘Общая ошибка. Проверьте код’console.log(commonError.name)// ‘Error’const commonError =newError(‘Общая ошибка. Проверьте код’)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)

Альтернативные варианты устранения ошибки

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

Установите на PC или лэптоп актуальную версию ОС Windows, на которую регулярно выходят официальные обновления Microsoft. Сегодня разработчики американской компании исправно обновляют только восьмерку и десятку. Поэтому выберите одну из этих операционок. Голосовой чат Discord – это относительно новое программное обеспечение, использующее современные службы и компоненты. Старые версии операционной системы не поддерживают их, поэтому возникают всевозможные сбои и ошибки.

Свойства объекта Error

СвойствоОписание
nameЗадает или возвращает имя ошибки
messageЗадает или возвращает сообщение об ошибке (строка)

Проверка HTML

Приведенный выше код является лишь примером.

Современные браузеры часто используют комбинацию JavaScript и встроенную проверку HTML, используя предопределенные правила проверки, определенные в атрибутах HTML:

Подробнее о проверке форм можно прочитать в следующей главе этого учебного пособия.

Как называть функции

Чтобы понять, как называть функции, давайте рассмотрим несколько примеров:

// анонимная функция
const one = () => {};

// анонимная функция
const two = function () {};

// функция с явным названием
const three = function explicitFunction() {};

Вот три примера функций.

Первая – это лямбда(или стрелочная функция). Лямбда функции по своей природе анонимны. Не запутайтесь. Имя переменной one не является именем функции. Имя функции следующее за ключевым словомfunction необязательно. Но в этом примере мы вообще ничего не передаем, поэтому наша функция анонимна.

ПримечаниеНе помогает и то, что некоторые среды выполнения JavaScript, такие как V8, могут иногда угадывать имя вашей функции. Это происходит, даже если вы его не даете.

Во втором примере мы получили функциональное выражение. Это очень похоже на первый пример. Это анонимная функция, но просто объявленная с помощью ключевого словаfunction вместо синтаксиса жирной стрелки.

В последнем примере объявление переменной с подходящим именем explicitFunction. Это показывает, что это единственная функция, у которой соответствующее имя.

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

Обёртывание исключений

Назначение функции readUser в приведённом выше коде – это «чтение данных пользователя». В процессе могут возникнуть различные виды ошибок. Сейчас у нас есть SyntaxError и ValidationError, но в будущем функция readUser может расшириться и, возможно, генерировать другие виды ошибок.

Код, который вызывает readUser, должен обрабатывать эти ошибки.

Сейчас в нём используются проверки if в блоке catch, которые проверяют класс и обрабатывают известные ошибки и пробрасывают дальше неизвестные. Но если функция readUser генерирует несколько видов ошибок, то мы должны спросить себя: действительно ли мы хотим проверять все типы ошибок поодиночке во всех местах в коде, где вызывается readUser?

Часто ответ «Нет»: внешний код хочет быть на один уровень выше всего этого. Он хочет иметь какую-то обобщённую ошибку чтения данных. Почему именно это произошло – часто не имеет значения (об этом говорится в сообщении об ошибке). Или даже лучше, если есть способ получить подробности об ошибке, но только если нам это нужно.

Итак, давайте создадим новый класс ReadError для представления таких ошибок. Если ошибка возникает внутри readUser, мы её перехватим и сгенерируем ReadError. Мы также сохраним ссылку на исходную ошибку в свойстве cause. Тогда внешний код должен будет только проверить наличие ReadError.

Этот код определяет ошибку ReadError и демонстрирует её использование в readUserи try..catch:

class ReadError extends Error {
constructor(message, cause) {
super(message);
this.cause = cause;
this.name = ‘ReadError’;
}
}

class ValidationError extends Error { /*…*/ }
class PropertyRequiredError extends ValidationError { /* … */ }

function validateUser(user) {
if (!user.age) {
throw new PropertyRequiredError(“age”);
}

if (!user.name) {
throw new PropertyRequiredError(“name”);
}
}

function readUser(json) {
let user;

try {
user = JSON.parse(json);
} catch (err) {
if (err instanceof SyntaxError) {
throw new ReadError(“Синтаксическая ошибка”, err);
} else {
throw err;
}
}

try {
validateUser(user);
} catch (err) {
if (err instanceof ValidationError) {
throw new ReadError(“Ошибка валидации”, err);
} else {
throw err;
}
}

}

try {
readUser(‘{bad json}’);
} catch (e) {
if (e instanceof ReadError) {
alert(e);
// Исходная ошибка: SyntaxError:Unexpected token b in JSON at position 1
alert(“Исходная ошибка: ” + e.cause);
} else {
throw e;
}
}

В приведённом выше коде readUser работает так, как описано – функция распознаёт синтаксические ошибки и ошибки валидации и выдаёт вместо них ошибки ReadError (неизвестные ошибки, как обычно, пробрасываются).

Внешний код проверяет только instanceof ReadError. Не нужно перечислять все возможные типы ошибок

Этот подход называется «обёртывание исключений», потому что мы берём «исключения низкого уровня» и «оборачиваем» их в ReadError, который является более абстрактным и более удобным для использования в вызывающем коде. Такой подход широко используется в объектно-ориентированном программировании.

Дополнение к уроку

Листочек

Самый действенный способ понять, как работает участок кода —
это расписать его выполнение на бумажке, как если бы вы были компьютером (медленным и немного голодным).

Зачем беспокоиться об обработке ошибок в Node.js?

Представьте, как разрабатываете RESTful web API на Node.js.

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

Как исправить ошибку «JavaScript error occurred in the main process»

Для исправления этой ошибки нужно на компьютере или ноутбуке открыть папку, куда была произведена установка файлов программы Discord. Нам понадобятся 2 папки программы Дискорд – «AppData» и «AppDataLocal». В некоторых версиях Windows папки могут быть скрыты по умолчанию. Поэтому чтобы открыть нужные нам папки:

  1. Откройте меню «Пуск».
  2. Выберите «Выполнить». Можно также нажать Win+R для быстрого доступа к строке «Выполнить» из рабочего стола.Команда %appdata%
    Команда %appdata%
  3. В открывшемся окне вводим фразу «%localappdata%» и «%appdata%» для открытия наших скрытых папок. В них нужно удалить все, что связано со словом «Discord».
  4. Из программы Discord нужно выйти. Самым удобным способом, в нашей ситуации, это открыть «Диспетчер задач» и «Убить» все процессы, где фигурирует слово «discord». Как это сделать для вашей версии ОС можно посмотреть в поисковике, вбив в строку нужный запрос.
  5. Теперь нужно удалить программу и заново установить, т.е. переустановить.
  6. Ошибка должна исчезнуть, а программа заработать без сбоев.
Источники

  • https://ru.code-basics.com/languages/javascript/lessons/errors
  • https://doka.guide/js/errors/
  • https://proglib.io/p/luchshie-praktiki-obrabotki-oshibok-v-node-js-2022-09-21
  • https://timeweb.com/ru/community/articles/oshibka-405-method-not-allowed-chto-za-oshibka-i-kak-ee-ispravit
  • https://artzolin.ru/javascript-theory/javascript-error-handling/
  • https://itfaza.ru/oshibka-javascript-error-occurred-in-the-main-process-prichiny-poyavleniya-i-sposoby-ustraneniya/
  • https://html5css.ru/js/js_errors.php
  • https://learn.javascript.ru/custom-errors
  • https://ru.hexlet.io/courses/introduction_to_programming/lessons/errors/theory_unit
  • https://lifehacki.ru/javascript-error-occurred-in-the-main-process/
[свернуть]
Решите Вашу проблему!


×
Adblock
detector