Якими ÑÑдовими пÑогÑамÑÑÑами ми б не бÑли, ÑаÑом ÑÑаплÑÑÑÑÑÑ, Ñо в наÑÐ¸Ñ ÑкÑипÑÐ°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ°ÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. Ðони можÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑÑи ÑеÑез наÑÑ Ð½ÐµÑважнÑÑÑÑ, непеÑедбаÑÑÐ²Ð°Ð½Ñ Ð²Ñ ÑÐ´Ð½Ñ Ð´Ð°Ð½Ñ Ð²Ñд коÑиÑÑÑваÑÑв, непÑавилÑÐ½Ñ Ð²ÑдповÑÐ´Ñ Ð²Ñд ÑеÑвеÑа або з ÑиÑÑÑ ÑнÑÐ¸Ñ Ð¿ÑиÑин.
ЯкÑо виникаÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, Ñо ÑкÑипÑи, зазвиÑай, âпомиÑаÑÑÑâ (ÑапÑово пÑипинÑÑÑÑ ÑобоÑÑ) Ñа виводÑÑÑ ÑнÑоÑмаÑÑÑ Ð¿Ñо Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ð² конÑолÑ.
Ðле ÑÑнÑÑ ÑинÑакÑиÑна конÑÑÑÑкÑÑÑ try...catch, Ñо дозволÑÑ Ð½Ð°Ð¼ âпеÑеÑ
оплÑваÑиâ помилки, Ñо Ð´Ð°Ñ Ð·Ð¼Ð¾Ð³Ñ ÑкÑипÑам виконаÑи поÑÑÑÐ±Ð½Ñ Ð´ÑÑ, а не ÑапÑово пÑипиниÑи ÑобоÑÑ.
СинÑакÑÐ¸Ñ âtryâ¦catchâ
ÐонÑÑÑÑкÑÑÑ try...catch мÑÑÑиÑÑ Ð´Ð²Ð° головниÑ
блоки: try, а поÑÑм catch:
try {
// код...
} catch (err) {
// код обÑобки помилки
}
Це пÑаÑÑÑ Ð½Ð°ÑÑÑпним Ñином:
- РпеÑÑÑ ÑеÑÐ³Ñ Ð²Ð¸ÐºÐ¾Ð½ÑÑÑÑÑÑ ÐºÐ¾Ð´ в блоÑÑ
try {...}. - ЯкÑо не Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, Ñо блок
catch (err)ÑгноÑÑÑÑÑÑÑ: Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ÑÑÐ³Ð°Ñ ÐºÑнÑÑ Ð±Ð»Ð¾ÐºÑtryÑа пÑодовжÑÑÑÑÑÑ Ð¿Ð¾Ð·Ð° блокомcatch. - ЯкÑо Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, ÑÐ¾Ð´Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð²
tryпÑипинÑÑÑÑÑÑ Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñ Ð¿ÑодовжÑÑÑÑÑÑ Ð· поÑаÑÐºÑ Ð±Ð»Ð¾ÐºÑcatch (err). ÐмÑннаerr(можна обÑаÑи бÑдÑ-Ñке ÑмâÑ) бÑде мÑÑÑиÑи обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ з додаÑÐºÐ¾Ð²Ð¾Ñ ÑнÑоÑмаÑÑÑÑ.
ÐÑже, помилка вÑеÑÐµÐ´Ð¸Ð½Ñ Ð±Ð»Ð¾ÐºÑ try {...} не пÑизводиÑÑ Ð´Ð¾ ÑапÑового пÑÐ¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ ÑобоÑи ÑкÑипÑÑ â ми оÑÑимÑÑмо можливÑÑÑÑ Ð¾Ð±ÑобиÑи ÑÑ Ð² catch.
ÐодивÑмоÑÑ Ð½Ð° декÑлÑка пÑикладÑв.
-
ÐÑиклад без винÑÑка: виводиÑÑ
alert(1)Ñа(2):try { alert('ÐоÑаÑок Ð±Ð»Ð¾ÐºÑ try'); // (1) <-- // ...код без помилок alert('ÐÑнеÑÑ Ð±Ð»Ð¾ÐºÑ try'); // (2) <-- } catch (err) { alert('Ðомилок немаÑ, ÑÐ¾Ð¼Ñ catch ÑгноÑÑÑÑÑÑÑ'); // (3) } -
ÐÑиклад з помилкоÑ: винÑÑком
(1)Ñа(3):try { alert('ÐоÑаÑок Ð±Ð»Ð¾ÐºÑ try'); // (1) <-- lalala; // помилка, variable is not defined! alert('ÐÑнеÑÑ Ð±Ð»Ð¾ÐºÑ try (не бÑде виконано)'); // (2) } catch (err) { alert(`Ðиникла помилка!`); // (3) <-- }
try...catch пÑаÑÑÑ ÑÑлÑки з винÑÑками, Ñо виникаÑÑÑ Ð¿Ñд ÑÐ°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÑкÑипÑÑЩоб блок try...catch ÑпÑаÑÑвав, код повинен запÑÑкаÑиÑÑ. ÐнÑими Ñловами, Ñе повинен бÑÑи валÑдний JavaScript код.
Це не ÑпÑаÑÑÑ, ÑкÑо код мÑÑÑиÑÑ ÑинÑакÑиÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, Ñк-Ð¾Ñ Ð½ÐµÐ·Ð°ÐºÑиÑÑ ÑÑгÑÑÐ½Ñ Ð´Ñжки:
try {
{{{{{{{{{{{{
} catch (err) {
alert("Це не валÑдний код, ÑÑÑÑй його не зÑозÑмÑÑ");
}
JavaScript ÑÑÑÑй ÑпоÑаÑÐºÑ Ð¿ÑоÑиÑÑÑ ÐºÐ¾Ð´ Ñ ÑÑлÑки поÑÑм виконÑÑ Ð¹Ð¾Ð³Ð¾. Ðомилки, Ñо виникаÑÑÑ Ñ ÑÐ°Ð·Ñ ÑиÑÐ°Ð½Ð½Ñ Ð½Ð°Ð·Ð¸Ð²Ð°ÑÑÑÑÑ âпомилки паÑÑингÑâ, вони не можÑÑÑ Ð±ÑÑи обÑобленими Ñ ÑкÑипÑи пÑипинÑÑÑÑ ÑÐ²Ð¾Ñ ÑобоÑÑ. Це Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ ÑеÑез Ñе, Ñо ÑÑÑÑй не може зÑозÑмÑÑи код.
Ð¢Ð¾Ð¼Ñ try...catch може ÑÑлÑки обÑоблÑÑи помилки, Ñо виникаÑÑÑ Ñ Ð¿ÑавилÑÐ½Ð¾Ð¼Ñ ÐºÐ¾Ð´Ñ. Ð¢Ð°ÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ називаÑÑÑ âпомилками пÑд ÑÐ°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñâ (runtime errors) або âвинÑÑкамиâ (exceptions).
Ð ÑкÑаÑнÑÑкÑй Ð¼Ð¾Ð²Ñ Ð²ÑдÑÑÑнÑй ÑоÑний вÑдповÑдник англÑйÑÑкого Ñлова âexceptionâ. Слово âвинÑÑокâ Ð´Ð»Ñ ÑкÑаÑÐ½Ð¾Ð¼Ð¾Ð²Ð½Ð¾Ñ Ð»Ñдини здаÑÑÑÑÑ Ð½Ðµ Ñаким зÑÑÑним Ñ Ð·ÑозÑмÑлим Ñк Ñлово âпомилкаâ. Ð Ñим не менÑ, Ñлово помилка вживаÑÑÑ Ð¿Ð¾ вÑдноÑÐµÐ½Ð½Ñ Ð´Ð¾ вÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº. Ð Ð´Ð»Ñ Ð¾ÐºÑемого пÑÐ´Ð²Ð¸Ð´Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, конкÑеÑно Ð´Ð»Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, Ñо ÑÑаÑÑÑÑÑ Ð¿Ñд ÑÐ°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñ, ÑÐ½Ð¾Ð´Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑ Ñлово винÑÑок. Ð¢Ð¾Ð¼Ñ ÐºÐ¾Ð»Ð¸ нижÑе баÑиÑимеÑе Ñлово âвинÑÑокâ, пÑоÑÑо знайÑе, Ñо мова йде пÑо помилкÑ.
try...catch пÑаÑÑÑ ÑинÑ
ÑонноЯкÑо винÑÑок ÑÑаплÑÑÑÑÑÑ Ñ âÐ·Ð°Ð¿Ð»Ð°Ð½Ð¾Ð²Ð°Ð½Ð¾Ð¼Ñ Ð´Ð¾ виконаннÑâ кодÑ, Ñк Ð¾Ñ Ð² setTimeout, ÑÐ¾Ð´Ñ try...catch не зможе пеÑеÑ
опиÑи помилкÑ:
try {
setTimeout(function() {
noSuchVariable; // ÑкÑÐ¸Ð¿Ñ Ð¿ÑипиниÑÑ ÑÐ²Ð¾Ñ ÑобоÑÑ
}, 1000);
} catch (err) {
alert( "не ÑпÑаÑÑÑ" );
}
Це вÑдбÑваÑÑÑÑÑ ÑеÑез Ñе, Ñо ÑÑнкÑÑÑ Ð±Ñде виконана пÑзнÑÑе, коли ÑÑÑÑй вже вийде з Ð±Ð»Ð¾ÐºÑ try...catch.
Щоб пеÑеÑ
опиÑи винÑÑок вÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑнкÑÑÑ Ð·Ð°Ð¿Ð»Ð°Ð½Ð¾Ð²Ð°Ð½Ð¾Ñ Ð´Ð¾ виконаннÑ, try...catch повинен бÑÑи вÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑÑÑ ÑÑнкÑÑÑ:
setTimeout(function() {
try {
noSuchVariable; // try...catch опÑаÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ!
} catch {
alert( "Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ð¿ÐµÑеÑ
оплено ÑÑÑ!" );
}
}, 1000);
ÐбâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸
Ðоли Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, JavaScript генеÑÑÑ Ð¾Ð±âÑкÑ, Ñо мÑÑÑиÑÑ ÑнÑоÑмаÑÑÑ Ð¿Ñо неÑ. ÐоÑÑм Ñей обâÑÐºÑ Ð¿ÐµÑедаÑÑÑÑÑ Ñк аÑгÑÐ¼ÐµÐ½Ñ Ð² catch:
try {
// ...
} catch (err) { // <-- "обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸", можна викоÑиÑÑаÑи ÑнÑÑ Ð½Ð°Ð·Ð²Ñ Ð·Ð°Ð¼ÑÑÑÑ err
// ...
}
ÐÐ»Ñ Ð²ÑÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ð¼Ð°Ñ Ð´Ð²Ñ Ð³Ð¾Ð»Ð¾Ð²Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ:
name- Ðазва помилки. Ðо пÑикладÑ, Ð´Ð»Ñ Ð½ÐµÐ¾Ð³Ð¾Ð»Ð¾ÑÐµÐ½Ð¾Ñ Ð·Ð¼ÑÐ½Ð½Ð¾Ñ Ð½Ð°Ð·Ð²Ð° бÑде
"ReferenceError". message- ТекÑÑове повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· додаÑÐºÐ¾Ð²Ð¾Ñ ÑнÑоÑмаÑÑÑÑ Ð¿Ñо помилкÑ.
ÐÑнÑÑÑÑ ÑнÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ, Ñо доÑÑÑÐ¿Ð½Ñ Ð² бÑлÑÑоÑÑÑ Ð¾ÑоÑенÑ. Ðдна з найÑживанÑÑÐ¸Ñ Ñа ÑаÑÑо пÑдÑÑимÑÐ²Ð°Ð½Ð¸Ñ :
stack- ÐоÑоÑний ÑÑек викликÑв: ÑÑдок з ÑнÑоÑмаÑÑÑÑ Ð¿Ñо поÑлÑдовнÑÑÑÑ Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð¸Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑв, Ñо пÑизвели до помилки. ÐикоÑиÑÑовÑÑÑÑÑÑ Ð´Ð»Ñ Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ.
ÐапÑиклад:
try {
lalala; // помилка, змÑнна не визнаÑена!
} catch (err) {
alert(err.name); // ReferenceError
alert(err.message); // lalala is not defined
alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)
// Також можливо вивеÑÑи Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ ÑÑлком
// ÐÐ¾Ð¼Ð¸Ð»ÐºÑ ÐºÐ¾Ð½Ð²ÐµÑÑовано в ÑÑдок ÑоÑмаÑÑ "name: message"
alert(err); // ReferenceError: lalala is not defined
}
ÐпÑÑоналÑнÑÑÑÑ Ð°ÑгÑменÑÑв âcatchâ блокÑ
Ðлок catch не обовâÑзково повинен пеÑеÑ
оплÑваÑи ÑнÑоÑмаÑÑÑ Ð¿Ñо обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸:
try {
// ...
} catch { // <-- без (err)
// ...
}
ÐикоÑиÑÑÐ°Ð½Ð½Ñ âtryâ¦catchâ
ÐодивÑмоÑÑ Ð½Ð° ÑеалÑний пÑиклад викоÑиÑÑÐ°Ð½Ð½Ñ try...catch.
Як ми вже знаÑмо, JavaScript може ÑиÑаÑи знаÑÐµÐ½Ð½Ñ Ñ ÑоÑмаÑÑ JSON за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¼ÐµÑÐ¾Ð´Ñ JSON.parse(str).
ÐазвиÑай ми викоÑиÑÑовÑÑмо його Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´ÑÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ Ð¾ÑÑÐ¸Ð¼Ð°Ð½Ð¸Ñ Ð· ÑеÑвеÑа Ñи ÑнÑого джеÑела ÑеÑез меÑежÑ.
Ðи оÑÑимÑÑмо Ð´Ð°Ð½Ñ Ñа викликаÑмо JSON.parse наÑÑÑпним Ñином:
let json = '{"name":"Ðван", "age": 30}'; // Ð´Ð°Ð½Ñ Ð· ÑеÑвеÑÑ
let user = JSON.parse(json); // ÑÑанÑÑоÑмÑÑмо ÑекÑÑове знаÑÐµÐ½Ð½Ñ Ð² JS обâÑкÑ
// ÑÐµÐ¿ÐµÑ user Ñе обâÑкÑ, Ñо мÑÑÑиÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð· ÑÑдка
alert( user.name ); // Ðван
alert( user.age ); // 30
Ðи можеÑе знайÑи бÑлÑÑе ÑнÑоÑмаÑÑÑ Ð¿Ñо викоÑиÑÑÐ°Ð½Ð½Ñ JSON в ÑоздÑÐ»Ñ ÐеÑоди JSON, toJSON.
ЯкÑо викоÑиÑÑаÑи JSON.parse з непÑавилÑно ÑÑоÑмованим json повÑдомленнÑм, Ñе пÑизведе до помилки Ñа ÑапÑового пÑÐ¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ ÑобоÑи ÑкÑипÑÑ.
Така поведÑнка задоволÑнÑÑ Ð½Ð°Ñ? ÐвиÑайно нÑ!
ÐоÑиÑÑÑÐ²Ð°Ñ Ð½Ñколи не дÑзнаÑÑÑÑÑ ÑкÑо з даними ÑоÑÑ ÑÑапилоÑÑ (ÑкÑо не вÑдкÑÐ¸Ñ ÐºÐ¾Ð½ÑÐ¾Ð»Ñ ÑозÑобника). ÐÑди не оÑÑкÑÑÑÑ, Ñо ÑоÑÑ ÑапÑово може пÑипиниÑи ÑобоÑÑ Ð±ÐµÐ· бÑдÑ-ÑÐºÐ¾Ñ ÑнÑоÑмаÑÑÑ Ð¿Ñо помилкÑ.
ÐÐ»Ñ Ð¾Ð±ÑÐ¾Ð±Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ викоÑиÑÑаймо try...catch:
let json = "{ непÑавилÑний ÑоÑÐ¼Ð°Ñ json }";
try {
let user = JSON.parse(json); // <-- ÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°...
alert( user.name ); // не бÑде виконано
} catch (err) {
// ...Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð¿ÐµÑедаÑÑÑÑÑ Ð² Ñей блок
alert( "ÐеÑепÑоÑÑÑмо, але Ð´Ð°Ð½Ñ Ð¼ÑÑÑÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. Ðи ÑпÑобÑÑмо запÑоÑиÑи ÑÑ
Ñе Ñаз." );
alert( err.name );
alert( err.message );
}
ТÑÑ Ð±Ð»Ð¾Ðº catch викоÑиÑÑали ÑÑлÑки Ð´Ð»Ñ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñо помилкÑ, але можна бÑло зÑобиÑи й ÑнÑÑ Ð´ÑÑ: вÑдпÑавиÑи новий запиÑ, запÑопонÑваÑи коÑиÑÑÑваÑÑ ÑнÑÑ Ð¾Ð¿ÑÑÑ, вÑдпÑавиÑи ÑнÑоÑмаÑÑÑ Ð¿Ñо Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ð´Ð»Ñ Ð»Ð¾Ð³ÑÐ²Ð°Ð½Ð½Ñ Ñа Ñн. ÐÑдÑ-Ñкий ÑпоÑÑб викоÑиÑÑÐ°Ð½Ð½Ñ ÐºÑаÑе, нÑж ÑапÑове пÑÐ¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ ÑобоÑи без жодниÑ
поÑÑненÑ.
СÑвоÑÐµÐ½Ð½Ñ Ñа Ð²ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð½Ð°ÑÐ¸Ñ Ð²Ð»Ð°ÑÐ½Ð¸Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº
УÑвÑмо ÑиÑÑаÑÑÑ, Ñо json ÑинÑакÑиÑно пÑавилÑний, але не мÑÑÑиÑÑ Ð½ÐµÐ¾Ð±Ñ
Ñдного Ð¿Ð¾Ð»Ñ name.
ÐапÑиклад:
let json = '{ "age": 30 }'; // Ð½ÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ
try {
let user = JSON.parse(json); // <-- помилка не виникаÑ
alert( user.name ); // вÑдÑÑÑÐ½Ñ Ð¿Ð¾Ð»Ðµ name!
} catch (err) {
alert( "не бÑде виконано" );
}
Ð ÑÐ°ÐºÐ¾Ð¼Ñ ÑÐ°Ð·Ñ JSON.parse ÑпÑаÑÑÑ Ð±ÐµÐ· винÑÑкÑв Ñ Ð±Ð»Ð¾Ðº catch бÑде пÑоÑгноÑованим. Ðле помилка в Ð½Ð°Ñ Ð²Ñеодно Ñ â вÑдÑÑÑнÑÑÑÑ Ð¿Ð¾Ð»Ñ name.
ÐÐ»Ñ Ñого, Ñоб ÑнÑÑÑкÑваÑи обÑÐ¾Ð±ÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, ми ÑкоÑиÑÑаÑмоÑÑ Ð¾Ð¿ÐµÑаÑоÑом throw.
ÐпеÑаÑÐ¾Ñ âthrowâ
ÐпеÑаÑÐ¾Ñ throw (з англ. кидаÑи, вкидаÑи) викоÑиÑÑовÑÑÑÑÑÑ Ð´Ð»Ñ Ð²ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
ÐпеÑаÑÐ¾Ñ Ð¼Ð°Ñ ÑинÑакÑиÑ:
throw <обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸>
СÑÑо ÑеÑ
нÑÑо ÑÑÑÑй JavaScript дозволÑÑ Ð¿ÐµÑедаваÑи бÑдÑ-ÑÐºÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð² ÑкоÑÑÑ Ð¾Ð±âÑкÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. Це може бÑÑи навÑÑÑ Ð¿ÑимÑÑивне знаÑеннÑ, Ñк ÑиÑло Ñи ÑÑдок. Ðле кÑаÑе викоÑиÑÑовÑваÑи обâÑкÑи, Ñо маÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ name Ñа message (Ð´Ð»Ñ ÑÑмÑÑноÑÑÑ Ð· вбÑдованим Ñипом помилок).
JavaScript Ð¼Ð°Ñ Ð±Ð°Ð³Ð°Ñо вбÑдованиÑ
конÑÑÑÑкÑоÑÑв Ð´Ð»Ñ Ð²Ð±ÑдованиÑ
помилок: Error, SyntaxError, ReferenceError, TypeError Ñа ÑнÑÑ. Також вони можÑÑÑ Ð±ÑÑи викоÑиÑÑаними Ð´Ð»Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð¾Ð±âÑкÑÑв помилок.
СинÑакÑÐ¸Ñ ÑнÑÑÑалÑзаÑÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº:
let error = new Error(message);
// or
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...
ÐÐ»Ñ Ð²Ð±Ñдованого ÑÐ¸Ð¿Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, влаÑÑивÑÑÑÑ name Ð¼Ð°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ ÑÐ¼ÐµÐ½Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑа, а message оÑÑимÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð· аÑгÑменÑÑ.
ÐапÑиклад:
let error = new Error("ЩоÑÑ ÑÑапилоÑÑ o_O");
alert(error.name); // Error
alert(error.message); // ЩоÑÑ ÑÑапилоÑÑ o_O
ÐодивÑмоÑÑ Ð½Ð° Ñип помилки, згенеÑований ÑÑнкÑÑÑÑ JSON.parse:
try {
JSON.parse("{ Ñе не json o_O }");
} catch (err) {
alert(err.name); // SyntaxError
alert(err.message); // expected property name or '}' at line 1 column 3 of the JSON data
}
Як баÑимо, назва помилки SyntaxError.
У ÑÐ°ÐºÐ¾Ð¼Ñ ÑÐ°Ð·Ñ Ð²ÑдÑÑÑнÑÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ name Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ñ, оÑкÑлÑки коÑиÑÑÑваÑам поÑÑÑбна ÑнÑоÑмаÑÑÑ Ð· ÑÑого полÑ.
Тож викинÑмо ÑÑ:
let json = '{ "age": 30 }'; // Ð½ÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ
try {
let user = JSON.parse(json); // <-- Ð½ÐµÐ¼Ð°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸
if (!user.name) {
throw new SyntaxError("ÐÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ: вÑдÑÑÑÐ½Ñ Ð¿Ð¾Ð»Ðµ name"); // (*)
}
alert( user.name );
} catch (err) {
alert( "JSON Error: " + err.message ); // JSON Error: ÐÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ: вÑдÑÑÑÐ½Ñ Ð¿Ð¾Ð»Ðµ name
}
У ÑÑÐ´ÐºÑ (*) опеÑаÑÐ¾Ñ throw генеÑÑÑ SyntaxError Ñз заданим знаÑеннÑм Ð¿Ð¾Ð»Ñ message, Ñаким же Ñином Ñе зÑобив би JavaScript. ÐÐ¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñ Ð² блоÑÑ try одÑÐ°Ð·Ñ Ð¿ÑипинÑÑÑÑÑÑ Ñ ÐºÐ¾Ð½ÑÑÐ¾Ð»Ñ Ð¿ÐµÑедаÑÑÑÑÑ Ð² catch.
Ð¢ÐµÐ¿ÐµÑ Ð² блоÑÑ catch обÑоблÑÑÑÑÑÑ Ð²ÑÑ Ð²Ð¸Ð´Ð¸ помилок: Ñк вÑд JSON.parse, Ñак Ñ ÐºÐ¾ÑиÑÑÑваÑÑкÑ.
ÐовÑоÑне Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº
РнаÑÑÑÐ¿Ð½Ð¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑаÑмо try...catch, Ñоб обÑобиÑи непÑавилÑÐ½Ñ Ð´Ð°Ð½Ñ. Ðле Ñи може вÑеÑÐµÐ´Ð¸Ð½Ñ Ð±Ð»Ð¾ÐºÑ try {...} виникнÑÑи ÑнÑа непеÑедбаÑÑвана помилка? ÐапÑиклад, Ñе не пÑоÑÑо âнепÑавилÑÐ½Ñ Ð´Ð°Ð½Ñâ, а пÑогÑамÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»Ð¸Ð²ÑÑ Ñ Ð·Ð°Ð±Ñв визнаÑиÑи змÑÐ½Ð½Ñ Ñи Ñе ÑоÑÑ?
ÐапÑиклад:
let json = '{ "age": 30 }'; // Ð½ÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ
try {
user = JSON.parse(json); // <-- не поÑÑавлено "let" пеÑед user
// ...
} catch (err) {
alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined
// (але пеÑеÑ
оплена помилка не повâÑзана з JSON Error)
}
ÐвиÑайно Ñаке можливо! ÐÑогÑамÑÑÑи Ñеж помилÑÑÑÑÑÑ. ÐавÑÑÑ Ð¿ÑогÑами з вÑдкÑиÑим кодом, Ñо викоÑиÑÑовÑÑÑÑÑÑ Ð´ÐµÑÑÑиÑÑÑÑÑми, можÑÑÑ ÑапÑово виÑвиÑиÑÑ Ð²Ñазливими.
РнаÑÐ¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ try...catch викоÑиÑÑовÑÑÑÑÑÑ Ð´Ð»Ñ Ð¿ÐµÑеÑ
Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, Ñо виникаÑÑÑ Ñ ÑÐ°Ð·Ñ Ð½ÐµÐ¿Ð¾Ð²Ð½Ð¸Ñ
даниÑ
. Ðле catch пеÑеÑ
оплÑÑ Ð²ÑÑ Ñипи помилок, Ñо виникаÑÑÑ Ð² try. ТÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð½ÐµÐ¿ÐµÑедбаÑÑвана помилка, але вÑе одно в повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ð¸Ð²Ð¾Ð´Ð¸ÑÑÑÑ "JSON Error". Це непÑавилÑна поведÑнка, Ñо ÑÑкладнÑÑ Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ.
Щоб ÑникаÑи ÑÐ°ÐºÐ¸Ñ Ð¿Ñоблем, ми можемо викоÑиÑÑовÑваÑи пÑÐ´Ñ Ñд âповÑоÑного Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðºâ (вÑд англ. rethrowing). ÐÑавило пÑоÑÑе:
Ðлок catch повинен обÑоблÑваÑи ÑÑлÑки вÑÐ´Ð¾Ð¼Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ñа повÑоÑно генеÑÑваÑи вÑÑ ÑнÑÑ Ñипи помилок.
РозглÑнÑмо пÑÐ´Ñ Ñд âповÑоÑного викиданнÑâ покÑоково:
- ÐонÑÑÑÑкÑÑÑ
catchпеÑÐµÑ Ð¾Ð¿Ð»ÑÑ Ð²ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. - РблоÑÑ
catch (err) {...}ми аналÑзÑÑмо обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸err. - ЯкÑо ми не знаÑмо Ñк пÑавилÑно обÑобиÑи помилкÑ, ми Ñобимо
throw err.
ÐазвиÑай, Ñип помилки можна пеÑевÑÑиÑи за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¾Ð¿ÐµÑаÑоÑа instanceof:
try {
user = { /*...*/ };
} catch (err) {
if (err instanceof ReferenceError) {
alert('ReferenceError'); // "ReferenceError": помилка доÑÑÑÐ¿Ñ Ð´Ð¾ невизнаÑÐµÐ½Ð¾Ñ Ð·Ð¼ÑнноÑ
}
}
ÐÐ»Ñ Ð²Ð¸Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ ÐºÐ»Ð°ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ можливо пеÑевÑÑиÑи влаÑÑивÑÑÑÑ err.name. ÐÑÑ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ маÑÑÑ ÑÑ. Також можна пеÑевÑÑиÑи знаÑÐµÐ½Ð½Ñ err.constructor.name.
У ÐºÐ¾Ð´Ñ Ð½Ð¸Ð¶Ñе, Ñоб catch опÑаÑÑовÑвав ÑÑлÑки SyntaxError, ми âповÑоÑно викидаÑмоâ помилки ÑнÑиÑ
ÑипÑв.
let json = '{ "age": 30 }'; // Ð½ÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ
try {
let user = JSON.parse(json);
if (!user.name) {
throw new SyntaxError("ÐÐµÐ¿Ð¾Ð²Ð½Ñ Ð´Ð°Ð½Ñ: вÑдÑÑÑÐ½Ñ Ð¿Ð¾Ð»Ðµ name");
}
blabla(); // непеÑедбаÑÑвана помилка
alert( user.name );
} catch (err) {
if (err instanceof SyntaxError) {
alert( "JSON Error: " + err.message );
} else {
throw err; // повÑоÑне Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ (*)
}
}
Ðомилка, Ñо Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð² ÑÑÐ´ÐºÑ (*), не пÑоÑ
одиÑÑ Ð¿ÐµÑевÑÑÐºÑ Ð² блоÑÑ catch Ñ Ð¿Ð¾Ð²ÑоÑно викидаÑÑÑÑÑ. ÐинÑÑок, пÑÑÐ»Ñ Ð¿Ð¾Ð²ÑоÑÐ½Ð¾Ñ Ð³ÐµÐ½ÐµÑаÑÑÑ, може Ð·Ð½Ð¾Ð²Ñ Ð±ÑÑи пеÑеÑ
опленим конÑÑÑÑкÑÑÑÑ try...catch (ÑкÑо вона ÑÑнÑÑ) або пÑизведе до аваÑÑйного пÑÐ¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ ÑобоÑи ÑкÑипÑÑ.
Така поведÑнка Ð±Ð»Ð¾ÐºÑ catch Ð´Ð°Ñ Ð·Ð¼Ð¾Ð³Ñ Ð¿ÐµÑеÑ
оплÑваÑи ÑÑлÑки ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, Ð´Ð»Ñ ÑкиÑ
пеÑедбаÑено пÑавила обÑобки, Ñа âпÑопÑÑкаÑиâ ÑеÑÑÑ ÑипÑв помилок.
ÐÑиклад нижÑе демонÑÑÑÑÑ, Ñк ÑеалÑзÑваÑи пеÑеÑ
Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ ÑакиÑ
помилок Ñе одним ÑÑвнем try...catch:
function readData() {
let json = '{ "age": 30 }';
try {
// ...
blabla(); // помилка!
} catch (err) {
// ...
if (!(err instanceof SyntaxError)) {
throw err; // повÑоÑне Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ (обÑобка ÑнÑого ÑÐ¸Ð¿Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº не пеÑедбаÑена)
}
}
}
try {
readData();
} catch (err) {
alert( "ÐовнÑÑÐ½Ñ Ð¿ÐµÑеÑ
опленнÑ: " + err ); // пеÑеÑ
оплено!
}
ФÑнкÑÑÑ readData дозволÑÑ Ð¾Ð¿ÑаÑÑовÑваÑи ÑÑлÑки SyntaxError помилки, а зовнÑÑнÑй блок try...catch Ð·Ð½Ð°Ñ Ñк опÑаÑÑваÑи бÑдÑ-Ñкий Ñип.
tryâ¦catchâ¦finally
ÐаÑекайÑе, бо Ñе Ñе не вÑе.
ÐонÑÑÑÑкÑÑÑ try...catch дозволÑÑ Ð´Ð¾Ð´Ð°Ñи Ñе один блок: finally.
ЯкÑо вÑн ÑÑнÑÑ, Ñо виконÑÑÑÑÑÑ Ð² бÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑазÑ:
- пÑÑлÑ
try, ÑкÑо помилка не виникла, - пÑÑлÑ
catch, ÑкÑо помилка бÑла пеÑÐµÑ Ð¾Ð¿Ð»ÐµÐ½Ð°.
РозÑиÑений ÑинÑакÑÐ¸Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ð°Ñ Ð½Ð°ÑÑÑпним Ñином:
try {
... ÑпÑоба виконаÑи код ...
} catch (err) {
... обÑобка помилки ...
} finally {
... завжди бÑде виконано ...
}
СпÑобÑйÑе запÑÑÑиÑи Ñей код:
try {
alert( 'try' );
if (confirm('Ðомилка поÑÑÑбна?')) BAD_CODE();
} catch (err) {
alert( 'catch' );
} finally {
alert( 'finally' );
}
Ðод Ð¼Ð°Ñ Ð´Ð²Ñ Ð³Ñлки Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ:
- ЯкÑо вÑдповÑÑÑи âÐаÑаздâ на âÐомилка поÑÑÑбна?â, бÑде
try -> catch -> finally. - ЯкÑо вÑдповÑÑÑи âСкаÑÑваÑиâ, ÑодÑ
try -> finally.
Ðлок finally викоÑиÑÑовÑÑÑÑÑÑ, ÑкÑо ми поÑали виконÑваÑи ÑкÑÑÑ ÑобоÑÑ Ñ Ñ
оÑемо завеÑÑиÑи ÑÑ Ð² бÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑазÑ.
ÐапÑиклад, ми Ñ
оÑемо вимÑÑÑÑи ÑÐ°Ñ ÑобоÑи ÑÑнкÑÑÑ, Ñо ÑаÑ
ÑÑ ÑиÑла ФÑбонаÑÑÑ. ÐÐ»Ñ ÑÑого ми можемо поÑаÑи вимÑÑÑÐ²Ð°Ð½Ð½Ñ Ð½Ð° поÑаÑÐºÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñ Ð·Ð°ÐºÑнÑиÑи пÑÑлÑ. Ð ÑкÑо пÑоÑÑгом ÑобоÑи ÑÑнкÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ½Ðµ помилка? ÐокÑема, ÑмплеменÑаÑÑÑ fib(n) нижÑе генеÑÑÑ Ð²Ð¸Ð½ÑÑки, ÑкÑо на вÑ
Ñд подано вÑдâÑмне або неÑÑле ÑиÑло.
ÐонÑÑÑÑкÑÑÑ finally â вÑдмÑнне мÑÑÑе Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÑÑÑÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ·Ð°Ð»ÐµÐ¶Ð½Ð¾ вÑд ÑезÑлÑÑаÑÑ.
Ðлок finally гаÑанÑÑÑ, Ñо ÑÐ°Ñ Ð±Ñде вимÑÑÑно пÑавилÑно Ñк в ÑиÑÑаÑÑÑ ÑÑпÑÑного виконаннÑ, Ñак Ñ Ð² ÑÐ°Ð·Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
let num = +prompt("ÐведÑÑÑ Ð´Ð¾Ð´Ð°Ñне ÑÑле ÑиÑло?", 35)
let diff, result;
function fib(n) {
if (n < 0 || Math.trunc(n) != n) {
throw new Error("ЧиÑло не повинно бÑÑи вÑдâÑмним або дÑобовим.");
}
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
let start = Date.now();
try {
result = fib(num);
} catch (err) {
result = 0;
} finally {
diff = Date.now() - start;
}
alert(result || "виникла помилка");
alert( `Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÑÑивало ${diff}мÑ` );
Ðи можеÑе пеÑевÑÑиÑи запÑÑÑивÑи код Ñ Ð²Ð²ÐµÑÑи 35 в prompt â ÑпеÑÑÑ Ð±Ñде виконано try, Ñ Ð·Ð° ним finally. Ð ÑÐ¾Ð´Ñ Ð²Ð²ÐµÑÑи -1, Ñ ÑÐ¾Ð´Ñ Ð±Ñде негайна помилка Ñ ÑезÑлÑÑÐ°Ñ Ð´Ð°ÑÑÑ 0мÑ. ÐÐ±Ð¸Ð´Ð²Ð¾Ñ Ð²Ð¸Ð¼ÑÑÑÐ²Ð°Ð½Ñ Ð±ÑдÑÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ñ ÐºÐ¾ÑекÑно.
ÐнакÑе кажÑÑи, ÑÑнкÑÑÑ Ð¼Ð¾Ð¶Ðµ завеÑÑÑваÑиÑÑ Ð°Ð±Ð¾ ÑеÑез return, або ÑеÑез throw, але блок finally бÑде завжди виконано.
try...catch...finally Ñ Ð»Ð¾ÐºÐ°Ð»ÑнимиÐвеÑнÑÑÑ ÑвагÑ, змÑÐ½Ð½Ñ result Ñа diff, в ÐºÐ¾Ð´Ñ Ð²Ð¸Ñе, оголоÑÐµÐ½Ñ Ð¿ÐµÑед try...catch.
ЯкÑо ми оголоÑимо змÑÐ½Ð½Ñ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ let в блоÑÑ try, вона залиÑиÑÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾Ñ ÑÑлÑки вÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑого блокÑ.
finally Ñа returnÐлок finally виконаÑÑÑÑÑ Ð² бÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑÐ°Ð·Ñ Ð¿Ñи виÑ
Ð¾Ð´Ñ Ð· try...catch. ÐавÑÑÑ ÑкÑо Ñвно викликаÑи return.
У пÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð½Ð¸Ð¶Ñе виÑ
Ñд з Ð±Ð»Ð¾ÐºÑ try вÑдбÑваÑÑÑÑÑ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ return. Ð¢Ð¾Ð´Ñ Ð±Ð»Ð¾Ðº finally бÑде виконано одÑÐ°Ð·Ñ Ð¿ÐµÑед повеÑненнÑм Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ зовнÑÑнÑого кодÑ.
function func() {
try {
return 1;
} catch (err) {
/* ... */
} finally {
alert( 'finally' );
}
}
alert( func() ); // ÑпоÑаÑÐºÑ ÑпÑаÑÑÑ alert з finally, а поÑÑм код в ÑÑÐ¾Ð¼Ñ ÑÑдкÑ
try...finallyÐонÑÑÑÑкÑÑÑ try...finally може не маÑи catch ÑаÑÑини, Ñо Ñакож може ÑÑаÑи Ñ Ð¿ÑигодÑ. Така конÑÑгÑÑаÑÑÑ Ð¼Ð¾Ð¶Ðµ бÑÑи викоÑиÑÑана, коли ми не Ñ
оÑемо пеÑеÑ
оплÑваÑи помилкÑ, але поÑÑÑбно завеÑÑиÑи ÑозпоÑаÑÑ Ð·Ð°Ð´Ð°ÑÑ.
function func() {
// ÑозпоÑаÑо задаÑÑ, Ñо поÑÑебÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ (напÑиклад вимÑÑÑваннÑ)
try {
// ...
} finally {
// закÑнÑиÑи задаÑÑ, навÑÑÑ ÑкÑо вÑе ÑапÑово пÑипинило ÑобоÑÑ
}
}
У ÐºÐ¾Ð´Ñ Ð²Ð¸Ñе помилка Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ try Ñа завжди пеÑедаÑÑÑÑÑ Ð²Ð¸Ñе в ÑÑÐµÐºÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÑв ÑеÑез вÑдÑÑÑнÑÑÑÑ catch, але finally виконаÑÑÑÑÑ Ð´Ð¾ Ñого, Ñк поÑÑк Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð²Ð¸Ð¹Ð´Ðµ з ÑÑнкÑÑÑ.
ÐлобалÑний catch
ÐнÑоÑмаÑÑÑ, Ñо наведена в ÑÑй окÑÐµÐ¼Ð¾Ñ ÑекÑÑÑ, не Ñ ÑÑандаÑÑом мови JavaScript.
ÐÑипÑÑÑимо, ÑеÑез Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ð¿ÑогÑамÑÑÑа винÑÑок ÑÑапивÑÑ Ð¿Ð¾Ð·Ð° блоком try...catch Ñ Ð¿Ñизвело до пÑÐ¸Ð¿Ð¸Ð½ÐµÐ½Ð½Ñ ÑобоÑи ÑкÑипÑÑ.
Як нам вÑиниÑи в ÑÐ°ÐºÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ? Ðи можемо логÑваÑи помилкÑ, виводиÑи повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐºÐ¾ÑиÑÑÑваÑÑ (пеÑеважно, коÑиÑÑÑваÑÑ Ð½Ðµ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð±Ð°ÑиÑи повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñо помилки) ÑоÑо.
СпеÑиÑÑкаÑÑÑ Ð½Ðµ згадÑÑ Ð¿Ñо ÑÐ°ÐºÑ Ð¼Ð¾Ð¶Ð»Ð¸Ð²ÑÑÑÑ, але оÑоÑеннÑ, зазвиÑай, надаÑÑÑ ÑÐ°ÐºÑ ÑÑнкÑÑÑ Ð´Ð»Ñ Ð·ÑÑÑноÑÑÑ. ÐапÑиклад, Node.js дозволÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñи process.on("uncaughtException") Ð´Ð»Ñ ÑÑого. У бÑаÑзеÑÑ Ð¼Ð¾Ð¶Ð½Ð° пÑиÑвоÑÑи ÑÑнкÑÑÑ ÑпеÑÑалÑнÑй влаÑÑивоÑÑÑ window.onerror, Ñо виконаÑÑÑÑÑ, коли виникне помилка.
СинÑакÑиÑ:
window.onerror = function(message, url, line, col, error) {
// ...
};
message- ÐовÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
url- URL ÑкÑипÑÑ, де ÑÑапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°.
line,col- ÐомеÑи ÑÑÐ´ÐºÑ Ñа колонки, де ÑÑапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°.
error- ÐбâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
ÐÑиклад:
<script>
window.onerror = function(message, url, line, col, error) {
alert(`${message}\n Ðомилка ÑÑапилаÑÑ Ð² ${line}:${col} з ${url}`);
};
function readData() {
badFunc(); // ТÑапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°!
}
readData();
</script>
ÐлобалÑний обÑобник window.onerror не пеÑедбаÑений Ð´Ð»Ñ Ð²ÑдновлÑÐ²Ð°Ð½Ð½Ñ ÑобоÑи ÑкÑипÑÑ, а ÑÑлÑки вÑдпÑÐ°Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñо Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ ÑозÑобникам.
ÐÐ»Ñ Ð»Ð¾Ð³ÑÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº Ñ ÑÐ°ÐºÐ¸Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÐ°Ñ ÑÑнÑÑÑÑ ÑпеÑÑалÑÐ½Ñ Ð²ÐµÐ±ÑеÑвÑÑи: https://errorception.com Ñи https://www.muscula.com.
Ðони пÑаÑÑÑÑÑ Ð½Ð°ÑÑÑпним Ñином:
- РозÑобник ÑеÑÑÑÑÑÑÑÑÑÑ Ð² ÑеÑвÑÑÑ Ñа оÑÑимÑÑ JS ÑкÑÐ¸Ð¿Ñ (Ñи URL ÑкÑипÑÑ), Ñкий поÑÑÑбно додаÑи на ÑÑоÑÑнкÑ.
- Цей ÑкÑÐ¸Ð¿Ñ Ð²ÑÑановлÑÑ Ð²Ð»Ð°ÑÐ½Ñ ÑÑнкÑÑÑ Ð²
window.onerror. - Ðоли ÑÑаплÑÑÑÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, ÑкÑÐ¸Ð¿Ñ Ð²ÑдпÑавлÑÑ Ð¼ÐµÑежевий Ð·Ð°Ð¿Ð¸Ñ Ð´Ð¾ ÑÑого ÑеÑвÑÑÑ.
- РозÑобник може зайÑи в ÑеÑвÑÑ Ñа пеÑеглÑдаÑи оÑÑÐ¸Ð¼Ð°Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
ÐÑдÑÑмки
ÐонÑÑÑÑкÑÑÑ try...catch дозволÑÑ Ð¾Ð±ÑоблÑÑи помилки, Ñо виникаÑÑÑ Ð¿ÑоÑÑгом ÑобоÑи ÑкÑипÑÑ. Це, в пÑÑÐ¼Ð¾Ð¼Ñ ÑенÑÑ, дозволÑÑ âÑпÑобÑваÑиâ виконаÑи код Ñа âпеÑеÑ
опиÑиâ помилки, Ñо можÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑÑи.
СинÑакÑиÑ:
try {
// Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñ
} catch (err) {
// ÑкÑо ÑÑапилаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°,
// пеÑедаÑи Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð² Ñей блок
} finally {
// завжди виконаÑÑÑÑÑ Ð¿ÑÑÐ»Ñ try/catch
}
Також ми можемо пÑопÑÑÑиÑи ÑекÑÑÑ catch Ñи finally, ÑÐ¾Ð¼Ñ ÑкоÑоÑÐµÐ½Ñ ÐºÐ¾Ð½ÑÑÑÑкÑÑÑ try...catch Ñа try...finally Ñеж валÑднÑ.
ÐбâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ð¼Ð°Ñ Ð½Ð°ÑÑÑÐ¿Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ:
messageâ ÑозбÑÑливе повÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñо помилкÑ.nameâ ÑÑдок з Ñменем помилки (назва конÑÑÑÑкÑоÑа помилки).stack(неÑÑандаÑÑна, але ÑиÑоко пÑдÑÑимÑвана) â ÑÑек викликÑв на Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
Ðи можемо пÑопÑÑÑиÑи оÑÑÐ¸Ð¼Ð°Ð½Ð½Ñ Ð¾Ð±âÑкÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ напиÑавÑи catch { замÑÑÑÑ catch (err) {.
Також ми можемо генеÑÑваÑи влаÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¾Ð¿ÐµÑаÑоÑа throw. ТеÑ
нÑÑно, бÑдÑ-Ñо можна пеÑедаÑи аÑгÑменÑом в throw, але, зазвиÑай, викоÑиÑÑовÑÑÑÑÑÑ Ð¾Ð±âÑкÑ, ÑÑпадкований вÑд вбÑдованого клаÑÑ Error. ÐеÑалÑнÑÑе пÑо ÑозÑиÑÐµÐ½Ð½Ñ Error бÑде в наÑÑÑÐ¿Ð½Ð¾Ð¼Ñ ÑоздÑлÑ.
ÐовÑоÑне Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ â важливий Ñаблон в ÑобоÑÑ Ð· помилками: пеÑеважно блок catch Ð·Ð½Ð°Ñ Ñк обÑоблÑÑи помилки певного ÑипÑ, ÑÐ¾Ð¼Ñ Ð²Ñн повинен Ð·Ð½Ð¾Ð²Ñ Ð²Ð¸ÐºÐ¸Ð´Ð°Ñи невÑÐ´Ð¾Ð¼Ñ Ñипи помилок.
ÐавÑÑÑ ÑкÑо ми не викоÑиÑÑовÑÑмо try...catch, бÑлÑÑÑÑÑÑ ÑеÑÐµÐ´Ð¾Ð²Ð¸Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑÑÑ Ð²ÑÑановиÑи âглобалÑнийâ обÑобник помилок. РбÑаÑзеÑаÑ
Ñе window.onerror.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)