Объект с ошибкой

Если возникает исключительная ситуация, то в первый параметр блока catch попадет объект со случившейся ошибкой. Свойство name этого объекта содержит имя ошибки (фактически ее тип), а свойство message - текст этой ошибки:

try { } catch (error) { console.log(error.name); // имя ошибки console.log(error.message); // текст ошибки }

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

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

Основные типы исключений

Давайте разберем 3 основных типа исключения, возникающих в JavaScript.

Исключение типа TypeError представляет собой ошибку, возникающую при недопустимом типе для переменной или параметра. Исключение типа SyntaxError представляет собой ошибку, возникающую при разборе исходного кода или JSON.

Исключение типа RangeError представляет собой ошибку, возникающую при попытке передать параметров в функцию число, которое не входит в допустимый диапазон значений параметра этой функции. Оно может возникать при создании массива с неправильной длиной через конструктор Array, или при передаче плохих значений в методы числа Number.toExponential(), Number.toFixed() или Number.toPrecision().

Существуют и другие типы исключений.

Применение типа исключения

Пусть у нас есть функция, параметром принимающая JSON с массивом данных и записывающая каждый элемент этого массива в локальное хранилище:

function saveData(json) { let arr = JSON.parse(json); for (let i = 0; i < arr.length; i++) { localStorage.setItem(i, arr[i]); } }

В данной функции исключительная ситуация может возникнуть в двух местах: при разборе JSON и при попытке сохранения данных в локальное хранилище.

Пусть, к примеру, в качестве обработки ошибок мы решили выводить некоторое сообщение о проблемах:

try { saveData('[1,2,3,4,5]'); } catch (error) { alert('какие-то проблемы'); }

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

Для этого отличим возникшие ошибки по имени:

try { saveData('[1,2,3,4,5]'); } catch (error) { if (error.name == 'QuotaExceededError') { alert('закончилось место в хранилище'); } if (error.name == 'SyntaxError') { alert('некорректный JSON'); } }

Скопируйте код моей функции saveData, а затем не подсматривая в мой код реализуйте описанную мною обработку ошибок.

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

Замечание

Можно обработку ошибок сделать внутри функции saveData:

function saveData(json) { try { let arr = JSON.parse(json); for (let i = 0; i < arr.length; i++) { try { localStorage.setItem(i, arr[i]); } catch (error) { alert('закончилось место в хранилище'); } } } catch (error) { alert('некорректный JSON'); } }

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

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

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