9. Помилки та винятки

JavaScript не має дуже розвиненої системи винятків. Проте він пропонує оператор [throw], який дозволяє повідомити про помилку, а також структуру try / catch / finally, що дозволяє перехоплювати ці помилки.
9.1. скрипт [excep-01]
У наведеному нижче скрипті ми відобразимо поточну дату у форматі [heures:minutes:secondes:millisecondes]. Для цього ми використаємо бібліотеку jS під назвою [moment.js]. Встановлюємо її, як зазвичай, за допомогою інструменту [npm]:

Код скрипта такий:
'use strict';
// пакет moment
import moment from 'moment';
...
Щоб дізнатися, як написати рядок [import] у рядку 4, можна переглянути визначення модуля [moment]:

- у [1-2] переходимо до визначення модуля;
- у [3] ми бачимо файл Typescript, а не Javascript. Під час виконання цей файл Typescript компілюється у файл Javascript перед тим, як його використовувати;
- у [4] шукаємо інструкції [export] (Ctrl-F);
- у [5] інструкція експортує об’єкт [moment]. Його можна імпортувати в ES6 таким чином:
import moment from 'moment';
Для імпорту об’єкта [moment] можна використовувати будь-яке ім’я, наприклад:
import m from 'moment';
Повернемося до коду скрипта:
'use strict';
// пакет moment
import moment from 'moment';
// принцип роботи try / catch / finally
for (let i = 0; i < 10; i++) {
// дата та час поточного моменту
const now = Date.now();
// форматування часу для отримання мілісекунд
const time = moment(now).format("HH:mm:ss:SSS");
// мілісекунди
const milli = Number(time.substr(time.length - 3));
// відображення
console.log("--------------------itération n° ", i, "à", time);
try {
// кількість варіантів залежно від поточного часу
const nbre = milli % 2;
if (nbre === 0) {
// вивести повідомлення про помилку
throw "erreur";
}
// якщо дійшли до цього місця, значить, помилки не сталося
console.log("pas d'erreur");
} catch (error) {
// якщо ви потрапили сюди, значить, сталася помилка
console.log("erreur1=", error);
} finally {
// виконується в будь-якому випадку, незалежно від наявності помилки
console.log("finally")
}
}
Коментарі
- рядок 4: імпорт бібліотеки [moment];
- принцип роботи скрипта полягає у виконанні циклу 10 разів (рядок 7). У кожному циклі отримується поточний час у форматі [heures:minutes:secondes:millisecondes] (рядки 8–13);
- якщо кількість мілісекунд парна, виводиться повідомлення про помилку (рядки 19–22);
- тут йдеться про розуміння принципу роботи конструкції try / catch / finally
Виконання
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-01.js"
--------------------itération n° 0 à 17:57:04:440
erreur1= erreur
finally
--------------------itération n° 1 à 17:57:04:447
pas d'erreur
finally
--------------------itération n° 2 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 3 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 4 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 5 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 6 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 7 à 17:57:04:448
erreur1= erreur
finally
--------------------itération n° 8 à 17:57:04:449
pas d'erreur
finally
--------------------itération n° 9 à 17:57:04:449
pas d'erreur
finally
Бачимо, що блок [finally] завжди виконується, незалежно від того, чи є помилка, чи ні.
9.2. скрипт [excep-02]
Цей скрипт, який може запускати оператор [throw], приймає дані будь-якого типу, і ці дані повністю обробляються блоком [catch].
'use strict';
// можна «викинути» (throw) практично що завгодно, щоб повідомити про помилку
let i = 0;
console.log("--------------------essai n° ", i);
// викинути рядок символів
try {
throw "msg d'erreur";
} catch (error) {
// сталася помилка
console.log("erreur=[", error, "], type=", typeof (error));
}
// створити масив
i++;
console.log("--------------------essai n° ", i);
try {
throw [1, 2, 3]
} catch (error) {
// сталася помилка
console.log("erreur=[", error, "], type=", typeof (error));
}
// запустити літеральний об’єкт
i++;
console.log("--------------------essai n° ", i);
try {
throw { nom: "hercule", pays: "grèce antique" }
} catch (error) {
// сталася помилка
console.log("erreur=[", error, "], type=", typeof (error));
}
// викликано тип Error
i++;
console.log("--------------------essai n° ", i);
try {
throw new Error("erreur de connexion au réseau");
} catch (error) {
// сталася помилка
console.log("erreur=[", error, "], type=", typeof (error));
}
// виник тип помилки Error
i++;
console.log("--------------------essai n° ", i);
try {
throw new Error("erreur de connexion au réseau");
} catch (error) {
// сталася помилка — повідомлення міститься в [error.message]
console.log("erreur.message=[", error.message, "], type(error)=", typeof (error));
}
Коментарі
- рядки 35, 44: [Error] — це клас JavaScript, конструктор якого приймає як перший необов’язковий параметр повідомлення про помилку. Це повідомлення можна отримати у властивості [Error.message] (рядок 47);
- існують й інші класи, крім [Error], для повідомлення про помилку: [EvalError, InternalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError);
Виконання
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-02.js"
--------------------essai n° 0
erreur=[ msg d'erreur ], type= string
--------------------essai n° 1
erreur=[ [ 1, 2, 3 ] ], type= object
--------------------essai n° 2
erreur=[ { nom: 'hercule', pays: 'grèce antique' } ], type= object
--------------------essai n° 3
erreur=[ Error: erreur de connexion au réseau
at Object.<anonymous> (c:\Data\st-2019\dev\es6\javascript\exceptions\excep-02.js:35:9)
at Object.<anonymous> (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:251206)
at c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:245054
at Generator.next (<anonymous>)
at bl (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:245412)
at kl (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:247659)
at Object.u (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:287740)
at Object.o (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:287137)
at Object.<anonymous> (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:284879)
at Object.apply (c:\Temp\19-09-01\javascript\node_modules\esm\esm.js:1:199341) ], type= object
--------------------essai n° 4
erreur.message=[ erreur de connexion au réseau ], type(error)= object
9.3. скрипт [excep-03]
Цей скрипт демонструє, що в [catch] можна розрізнити тип екземпляра [Error], перехопленого [catch]:
'use strict';
// пакет moment
import moment from 'moment';
// розрізнити екземпляр Error, отриманий у [catch]
for (let i = 0; i < 10; i++) {
// дата та час поточного моменту
const now = Date.now();
// форматування часу для отримання мілісекунд
const time = moment(now).format("HH:mm:ss:SSS");
// мілісекунди
const milli = Number(time.substr(time.length - 3));
console.log("--------------------itération n° ", i);
try {
// число [0, 1, 2]
const nbre = milli % 3;
switch (nbre) {
case 0:
throw new ReferenceError("erreur 1");
case 1:
throw new RangeError("erreur 2");
default:
throw new EvalError("erreur 3");
}
} catch (error) {
// сталася помилка
if (error instanceof ReferenceError) {
console.log("ReferenceError :", error.message);
} else {
if (error instanceof RangeError) {
console.log("RangeError :", error.message);
}
else {
if (error instanceof EvalError) {
console.log("EvalError :", error.message);
}
}
}
}
}
Виконання
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\exceptions\excep-03.js"
--------------------itération n° 0
ReferenceError : erreur 1
--------------------itération n° 1
RangeError : erreur 2
--------------------itération n° 2
RangeError : erreur 2
--------------------itération n° 3
RangeError : erreur 2
--------------------itération n° 4
RangeError : erreur 2
--------------------itération n° 5
RangeError : erreur 2
--------------------itération n° 6
EvalError : erreur 3
--------------------itération n° 7
EvalError : erreur 3
--------------------itération n° 8
EvalError : erreur 3
--------------------itération n° 9
EvalError : erreur 3