Ðоли ми ÑоÑÑ ÑозÑоблÑÑмо, нам ÑаÑÑо поÑÑÑÐ±Ð½Ñ Ð²Ð»Ð°ÑÐ½Ñ ÐºÐ»Ð°Ñи помилок, Ñоб вÑдобÑажаÑи конкÑеÑÐ½Ñ ÑеÑÑ, ÑÐºÑ Ð¼Ð¾Ð¶ÑÑÑ Ð¿ÑÑи не Ñак Ñ Ð½Ð°ÑиÑ
пÑогÑамаÑ
. ÐÐ»Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº Ñ Ð¼ÐµÑежевиÑ
опеÑаÑÑÑÑ
нам може знадобиÑиÑÑ HttpError, Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑÑй з Ð±Ð°Ð·Ð¾Ñ Ð´Ð°Ð½Ð¸Ñ
DbError, Ð´Ð»Ñ Ð¿Ð¾ÑÑÐºÑ Ð¾Ð¿ÐµÑаÑÑй NotFoundError ÑоÑо.
ÐаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð¿ÑдÑÑимÑваÑи оÑÐ½Ð¾Ð²Ð½Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, ÑÐ°ÐºÑ Ñк message, name Ñ, бажано, stack. Ðле вони Ñакож можÑÑÑ Ð¼Ð°Ñи ÑнÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ, напÑиклад, обâÑкÑи HttpError можÑÑÑ Ð¼Ð°Ñи влаÑÑивÑÑÑÑ statusCode Ð·Ñ Ð·Ð½Ð°ÑеннÑм, Ñк-Ð¾Ñ 404, 403 або 500.
JavaScript дозволÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи throw з бÑдÑ-Ñким аÑгÑменÑом, ÑÐ¾Ð¼Ñ ÑеÑ
нÑÑно наÑÑ ÑпеÑÑалÑÐ½Ñ ÐºÐ»Ð°Ñи помилок не Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ ÑÑпадковÑваÑиÑÑ Ð²Ñд Error. Ðле ÑкÑо ми ÑÑпадкÑÑмо, Ñо ÑÑÐ°Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¸Ð¼ викоÑиÑÑовÑваÑи obj instanceof Error Ð´Ð»Ñ ÑденÑиÑÑкаÑÑÑ Ð¾Ð±âÑкÑÑв помилки. Ð¢Ð¾Ð¼Ñ ÐºÑаÑе ÑÑпадкÑваÑи вÑд нÑого.
У мÑÑÑ ÑозвиÑÐºÑ Ð¿ÑогÑами наÑÑ Ð²Ð»Ð°ÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, пÑиÑоднÑо, ÑÑвоÑÑÑÑÑ ÑÑÑаÑÑ
ÑÑ. ÐапÑиклад, HttpTimeoutError може ÑÑпадковÑваÑиÑÑ Ð²Ñд HttpError ÑоÑо.
РозÑиÑÐµÐ½Ð½Ñ Error
Як пÑиклад, давайÑе ÑозглÑнемо ÑÑнкÑÑÑ readUser(json), Ñка повинна ÑиÑаÑи JSON з даними коÑиÑÑÑваÑа.
ÐÑÑ Ð¿Ñиклад Ñого, Ñк може виглÑдаÑи валÑдний json:
let json = `{ "name": "Ðван", "age": 30 }`;
ÐÑеÑÐµÐ´Ð¸Ð½Ñ Ð¼Ð¸ бÑдемо викоÑиÑÑовÑваÑи JSON.parse. ЯкÑо вÑн оÑÑимÑÑ Ð½ÐµÐ¿ÑавилÑний json, вÑн Ð²Ð¸ÐºÐ¸Ð´Ð°Ñ SyntaxError. Ðле навÑÑÑ ÑкÑо json ÑинÑакÑиÑно пÑавилÑний, Ñе не ознаÑаÑ, Ñо Ñе валÑдний коÑиÑÑÑваÑ, Ñи не Ñак? У нÑÐ¾Ð¼Ñ Ð¼Ð¾Ð¶Ðµ не бÑÑи необÑ
ÑдниÑ
нам даниÑ
. ÐапÑиклад, вÑн може не маÑи влаÑÑивоÑÑей name Ñа age, ÑÐºÑ Ñ Ð²Ð°Ð¶Ð»Ð¸Ð²Ð¸Ð¼Ð¸ Ð´Ð»Ñ Ð½Ð°ÑиÑ
коÑиÑÑÑваÑÑв.
ÐаÑа ÑÑнкÑÑÑ readUser(json) не ÑÑлÑки ÑиÑаÑиме JSON, але й пеÑевÑÑÑÑеме (âвалÑдÑваÑимеâ) данÑ. ЯкÑо Ð½ÐµÐ¼Ð°Ñ Ð¾Ð±Ð¾Ð²âÑзковиÑ
полÑв або ÑоÑÐ¼Ð°Ñ Ð½ÐµÐ¿ÑавилÑний, Ñе помилка. Ð Ñе не SyntaxError, оÑкÑлÑки Ð´Ð°Ð½Ñ ÑинÑакÑиÑно пÑавилÑнÑ, а ÑнÑий Ñип помилки. Ðи назвемо його ValidationError Ñ ÑÑвоÑимо Ð´Ð»Ñ Ð½Ñого окÑемий клаÑ. ÐодÑбна помилка Ñакож повинна мÑÑÑиÑи ÑнÑоÑмаÑÑÑ Ð¿Ñо поле, Ñо поÑÑÑÑÑ Ð¿Ñавила.
ÐÐ°Ñ ÐºÐ»Ð°Ñ ValidationError Ð¼Ð°Ñ ÑÑпадковÑваÑиÑÑ Ð²Ñд клаÑÑ Error.
ÐÐ»Ð°Ñ Error Ñ Ð²Ð±Ñдованим, але оÑÑ Ð¹Ð¾Ð³Ð¾ пÑиблизний код, Ñоб ми могли зÑозÑмÑÑи, Ñо ми ÑозÑиÑÑÑмо:
// "ÐÑевдокод" Ð´Ð»Ñ Ð²Ð±Ñдованого клаÑÑ Error, визнаÑеного Ñамим JavaScript
class Error {
constructor(message) {
this.message = message;
this.name = "Error"; // (ÑÑÐ·Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ Ð´Ð»Ñ ÑÑзниÑ
вбÑдованиÑ
клаÑÑв помилок)
this.stack = <call stack>; // неÑÑандаÑÑна влаÑÑивÑÑÑÑ, але бÑлÑÑÑÑÑÑ ÑеÑÐµÐ´Ð¾Ð²Ð¸Ñ ÑÑ Ð¿ÑдÑÑимÑÑ
}
}
Ð¢ÐµÐ¿ÐµÑ Ð´Ð°Ð²Ð°Ð¹Ñе ÑÑпадкÑÑмо вÑд нÑого Ð½Ð°Ñ ValidationError Ñ ÑпÑобÑÑмо його в дÑÑ:
class ValidationError extends Error {
constructor(message) {
super(message); // (1)
this.name = "ValidationError"; // (2)
}
}
function test() {
throw new ValidationError("УпÑ!");
}
try {
test();
} catch(err) {
alert(err.message); // УпÑ!
alert(err.name); // ValidationError
alert(err.stack); // ÑпиÑок вкладениÑ
викликÑв з номеÑами ÑÑдкÑв Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾
}
ÐвеÑнÑÑÑ ÑвагÑ: Ñ ÑÑÐ´ÐºÑ (1) ми викликаÑмо баÑÑкÑвÑÑкий конÑÑÑÑкÑоÑ. JavaScript Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ Ð²Ñд Ð½Ð°Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñи super Ñ Ð´Ð¾ÑÑÑнÑÐ¾Ð¼Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑÑ, Ñе обовâÑзково. ÐаÑÑкÑвÑÑкий конÑÑÑÑкÑÐ¾Ñ Ð²ÑÑановлÑÑ Ð²Ð»Ð°ÑÑивÑÑÑÑ message.
ÐаÑÑкÑвÑÑкий конÑÑÑÑкÑÐ¾Ñ Ñакож вÑÑановлÑÑ Ð´Ð»Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ name знаÑÐµÐ½Ð½Ñ "Error", ÑÐ¾Ð¼Ñ Ð² ÑÑÐ´ÐºÑ (2) ми ÑкидаÑмо його до поÑÑÑбного знаÑеннÑ.
ÐавайÑе ÑпÑобÑÑмо викоÑиÑÑаÑи його в readUser(json):
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
// Usage
function readUser(json) {
let user = JSON.parse(json);
if (!user.age) {
throw new ValidationError("No field: age");
}
if (!user.name) {
throw new ValidationError("No field: name");
}
return user;
}
// РобоÑий пÑиклад Ñз try..catch
try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
alert("Invalid data: " + err.message); // Invalid data: No field: name
} else if (err instanceof SyntaxError) { // (*)
alert("JSON Syntax Error: " + err.message);
} else {
throw err; // невÑдома помилка, пÑокинемо ÑÑ Ð´Ð°Ð»Ñ (**)
}
}
Ðлок try..catch Ñ ÐºÐ¾Ð´Ñ Ð²Ð¸Ñе обÑоблÑÑ Ñк наÑÑ ValidationError, Ñак Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ñ SyntaxError з JSON.parse.
ÐÑÐ´Ñ Ð»Ð°Ñка, подивÑÑÑÑÑ, Ñк ми викоÑиÑÑовÑÑмо instanceof Ð´Ð»Ñ Ð¿ÐµÑевÑÑки певного ÑÐ¸Ð¿Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ в ÑÑÐ´ÐºÑ (*).
Ðи Ñакож можемо викоÑиÑÑаÑи err.name, оÑÑ Ñак:
// ...
// замÑÑÑÑ (err instanceof SyntaxError)
} else if (err.name == "SyntaxError") { // (*)
// ...
ÐеÑÑÑÑ Ð· instanceof набагаÑо кÑаÑа, ÑÐ¾Ð¼Ñ Ñо в майбÑÑнÑÐ¾Ð¼Ñ Ð¼Ð¸ можемо ÑозÑиÑиÑи ValidationError, Ñоб ÑÑвоÑÑваÑи його пÑдÑипи, напÑиклад, PropertyRequiredError. РпеÑевÑÑка instanceof бÑде Ñакож пÑаÑÑваÑи Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ
ÑпадковиÑ
клаÑÑв. Так Ñо Ñе ÑÑÑÐµÐ½Ð½Ñ Ð·Ð°Ð»Ð¸ÑиÑÑÑÑ Ð½Ð°Ð´Ñйним Ñ Ð´Ð°Ð»Ñ.
Також важливо, Ñо ÑкÑо catch зÑÑÑÑÑÑÐ°Ñ Ð½ÐµÐ²ÑÐ´Ð¾Ð¼Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ, вÑн повÑоÑно Ð²Ð¸ÐºÐ¸Ð´Ð°Ñ ÑÑ Ð² ÑÑдок (**). ÐÐ°Ñ Ð±Ð»Ð¾Ðº catch Ð·Ð½Ð°Ñ Ð»Ð¸Ñе, Ñк обÑоблÑÑи помилки пеÑевÑÑки пÑавилÑноÑÑÑ Ð´Ð°Ð½Ð¸Ñ
Ñа ÑинÑакÑиÑÑ, ÑнÑÑ Ñипи (ÑпÑиÑÐ¸Ð½ÐµÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¾Ñ Ð² ÐºÐ¾Ð´Ñ Ð°Ð±Ð¾ ÑнÑими невÑдомими пÑиÑинами) поÑÑÑбно пÑокинÑÑи далÑ.
ÐодалÑÑе наÑлÑдÑваннÑ
ÐÐ»Ð°Ñ ValidationError дÑже загалÑний. ÐагаÑо Ñого може пÑÑи не Ñак. ÐлаÑÑивÑÑÑÑ Ð¼Ð¾Ð¶Ðµ бÑÑи вÑдÑÑÑÐ½Ñ Ð°Ð±Ð¾ ÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð¼Ð°Ñ Ð½ÐµÐ¿ÑавилÑний Ñип (напÑиклад, ÑÑдок Ñ age замÑÑÑÑ ÑиÑла). ÐавайÑе ÑÑвоÑимо бÑлÑÑ ÐºÐ¾Ð½ÐºÑеÑний ÐºÐ»Ð°Ñ PropertyRequiredError, Ñаме Ð´Ð»Ñ Ð²ÑдÑÑÑнÑÑ
влаÑÑивоÑÑей. ÐÑн мÑÑÑиÑиме додаÑÐºÐ¾Ð²Ñ ÑнÑоÑмаÑÑÑ Ð¿Ñо влаÑÑивÑÑÑÑ, ÑÐºÐ¾Ñ Ð½ÐµÐ¼Ð°Ñ.
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
class PropertyRequiredError extends ValidationError {
constructor(property) {
super("No property: " + property);
this.name = "PropertyRequiredError";
this.property = property;
}
}
// Usage
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("Invalid data: " + err.message); // Invalid data: No property: name
alert(err.name); // PropertyRequiredError
alert(err.property); // name
} else if (err instanceof SyntaxError) {
alert("JSON Syntax Error: " + 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("No property: " + property);
this.property = property;
}
}
// пÑавилÑна name
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError
Ð¢ÐµÐ¿ÐµÑ Ð½Ð°ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ набагаÑо коÑоÑÑÑ, оÑобливо ValidationError, оÑкÑлÑки ми позбÑлиÑÑ ÑÑдка "this.name = ..." Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑÑ.
ÐбгоÑÑÐ°Ð½Ð½Ñ Ð²Ð¸Ð½ÑÑкÑв
ÐеÑÐ¾Ñ ÑÑнкÑÑÑ readUser Ñ ÐºÐ¾Ð´Ñ Ð²Ð¸Ñе Ñ âÑиÑаÑи Ð´Ð°Ð½Ñ ÐºÐ¾ÑиÑÑÑваÑаâ. У пÑоÑеÑÑ Ð¼Ð¾Ð¶ÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ°Ñи ÑÑзного ÑÐ¾Ð´Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. ÐаÑаз ми маÑмо SyntaxError Ñ ValidationError, але в майбÑÑнÑÐ¾Ð¼Ñ ÑÑнкÑÑÑ readUser може бÑÑи ÑозÑиÑино Ñ, ймовÑÑно, вона генеÑÑваÑиме ÑнÑÑ Ð²Ð¸Ð´Ð¸ помилок.
Ð¢Ð¾Ð¼Ñ ÐºÐ¾Ð´, Ñкий Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ readUser, повинен обÑоблÑÑи ÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. ÐаÑаз вÑн викоÑиÑÑовÑÑ ÐºÑлÑка if Ñ Ð±Ð»Ð¾ÑÑ catch, ÑÐºÑ Ð¿ÐµÑевÑÑÑÑÑÑ ÐºÐ»Ð°Ñ, обÑоблÑÑÑÑ Ð²ÑÐ´Ð¾Ð¼Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ñа пÑокидÑÑÑÑ Ð´Ð°Ð»Ñ Ð½ÐµÐ²ÑдомÑ.
Ð¡Ñ ÐµÐ¼Ð° Ñака:
try {
...
readUser() // поÑенÑÑйне джеÑело помилки
...
} catch (err) {
if (err instanceof ValidationError) {
// обÑобиÑи помилки пеÑевÑÑки даниÑ
} else if (err instanceof SyntaxError) {
// обÑобиÑи ÑинÑакÑиÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸
} else {
throw err; // невÑдома помилка, пÑокинÑÑи далÑ
}
}
У ÐºÐ¾Ð´Ñ Ð²Ð¸Ñе ми баÑимо два Ñипи помилок, але ÑÑ Ð¼Ð¾Ð¶Ðµ бÑÑи бÑлÑÑе.
ЯкÑо ÑÑнкÑÑÑ readUser генеÑÑÑ ÐºÑлÑка ÑипÑв помилок, ÑÐ¾Ð´Ñ Ð¼Ð¸ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸ÑаÑи Ñебе: Ñи дÑйÑно ми Ñ
оÑемо ÑоÑÐ°Ð·Ñ Ð¿ÐµÑевÑÑÑÑи вÑÑ Ñипи помилок Ð¾Ð´Ð½Ñ Ð·Ð° одноÑ?
ЧаÑÑо вÑдповÑÐ´Ñ âнÑâ: ми б Ñ Ð¾ÑÑли бÑÑи âна один ÑÑÐ²ÐµÐ½Ñ Ð²Ð¸Ñе вÑÑого ÑÑогоâ. Ðи пÑоÑÑо Ñ Ð¾Ñемо знаÑи, Ñи ÑÑалаÑÑ âпомилка ÑиÑÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ â â ÑÐ¾Ð¼Ñ Ñаме Ñе ÑÑалоÑÑ, ÑаÑÑо не Ð¼Ð°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ (Ñе опиÑÑÑ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñо помилкÑ). Ðбо, Ñе кÑаÑе, ми Ñ Ð¾ÑÑли б маÑи ÑпоÑÑб оÑÑимаÑи деÑÐ°Ð»Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, але лиÑе за Ð½ÐµÐ¾Ð±Ñ ÑдноÑÑÑ.
Ð¢ÐµÑ Ð½Ñка, ÑÐºÑ Ð¼Ð¸ ÑÑÑ Ð¾Ð¿Ð¸ÑÑÑмо, називаÑÑÑÑÑ âобгоÑÑÐ°Ð½Ð½Ñ Ð²Ð¸Ð½ÑÑкÑвâ.
- Ðи ÑÑвоÑимо новий клаÑ
ReadError, Ñоб пÑедÑÑавлÑÑи загалÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ âÑиÑÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ â. - ФÑнкÑÑÑ
readUserбÑде ловиÑи помилки ÑиÑÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ , ÑÐºÑ Ð²Ð¸Ð½Ð¸ÐºÐ°ÑÑÑ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ Ð½ÐµÑ, напÑиклад,ValidationErrorÑSyntaxError, Ñ Ð½Ð°ÑомÑÑÑÑ Ð³ÐµÐ½ÐµÑÑваÑимеReadError. - ÐбâÑкÑ
ReadErrorзбеÑÑгаÑиме поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ð²Ð¸Ñ ÑÐ´Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ñ ÑвоÑй влаÑÑивоÑÑÑcause.
Ð¢Ð¾Ð´Ñ ÐºÐ¾Ð´, Ñкий Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ readUser, повинен бÑде пеÑевÑÑÑÑи лиÑе ReadError, а не вÑÑ Ð²Ð¸Ð´Ð¸ помилок ÑиÑÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ
. Ð ÑкÑо Ð¹Ð¾Ð¼Ñ Ð¿Ð¾ÑÑÑÐ±Ð½Ñ Ð´Ð¾Ð´Ð°ÑÐºÐ¾Ð²Ñ Ð²ÑдомоÑÑÑ Ð¿Ñо помилкÑ, вÑн може пеÑевÑÑиÑи ÑÑ Ð²Ð»Ð°ÑÑивÑÑÑÑ cause.
ÐÑÑ ÐºÐ¾Ð´, Ñкий визнаÑÐ°Ñ 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("Syntax Error", err);
} else {
throw err;
}
}
try {
validateUser(user);
} catch (err) {
if (err instanceof ValidationError) {
throw new ReadError("Validation Error", err);
} else {
throw err;
}
}
}
try {
readUser('{bad json}');
} catch (e) {
if (e instanceof ReadError) {
alert(e);
// Original error: SyntaxError: Unexpected token b in JSON at position 1
alert("Original error: " + e.cause);
} else {
throw e;
}
}
У Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе ÐºÐ¾Ð´Ñ readUser пÑаÑÑÑ, Ñк опиÑано â ловиÑÑ ÑинÑакÑиÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ñа помилки пеÑевÑÑки даниÑ
Ñа замÑÑÑÑ ÑÑого ÐºÐ¸Ð´Ð°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ ReadError (невÑÐ´Ð¾Ð¼Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ пÑокидÑÑÑÑÑÑ Ð´Ð°Ð»Ñ, Ñк Ñ ÑанÑÑе).
ÐÑже, зовнÑÑнÑй код пеÑевÑÑÑÑ instanceof ReadError Ñ Ð²Ñе. ÐÐµÐ¼Ð°Ñ Ð½ÐµÐ¾Ð±Ñ
ÑдноÑÑÑ Ð¿ÐµÑевÑÑÑÑи вÑÑ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ñ Ñипи помилок.
Цей пÑдÑ
Ñд називаÑÑÑÑÑ âобгоÑÑÐ°Ð½Ð½Ñ Ð²Ð¸Ð½ÑÑкÑвâ, ÑÐ¾Ð¼Ñ Ñо ми беÑемо винÑÑки âнизÑкого ÑÑвнÑâ Ñ âзагоÑÑаÑмоâ ÑÑ
Ñ ReadError, Ñо Ñ Ð±ÑлÑÑ Ð°Ð±ÑÑÑакÑним. Такий пÑдÑ
Ñд ÑиÑоко викоÑиÑÑовÑÑÑÑÑÑ Ð² обâÑкÑно-оÑÑÑнÑÐ¾Ð²Ð°Ð½Ð¾Ð¼Ñ Ð¿ÑогÑамÑваннÑ.
ÐÑдÑÑмки
- ÐазвиÑай клаÑи ÑвоÑÑ
помилок ми можемо ÑÑпадковÑваÑи вÑд
ErrorÑа ÑнÑÐ¸Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ»Ð°ÑÑв. Ðам пÑоÑÑо поÑÑÑбно подбаÑи пÑо влаÑÑивÑÑÑÑnameÑ Ð½Ðµ забÑÑи викликаÑиsuper. - Ðи можемо викоÑиÑÑовÑваÑи
instanceofÐ´Ð»Ñ Ð¿ÐµÑевÑÑки Ð¿ÐµÐ²Ð½Ð¸Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº. Це Ñакож пÑаÑÑÑ Ð·Ñ ÑпадковÑÑÑÑ. Ðле ÑÐ½Ð¾Ð´Ñ Ð¼Ð¸ маÑмо обâÑÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, Ñкий Ð½Ð°Ð´Ñ Ð¾Ð´Ð¸ÑÑ Ñз бÑблÑоÑеки вÑд ÑÑоÑоннÑÑ ÑозÑобникÑв, Ñ Ð½ÐµÐ¼Ð°Ñ Ð¿ÑоÑÑого ÑпоÑÐ¾Ð±Ñ Ð¾ÑÑимаÑи його клаÑ. Ð¢Ð¾Ð´Ñ Ð´Ð»Ñ ÑÐ°ÐºÐ¸Ñ Ð¿ÐµÑевÑÑок можна викоÑиÑÑовÑваÑи влаÑÑивÑÑÑÑname. - ÐбгоÑÑÐ°Ð½Ð½Ñ Ð²Ð¸Ð½ÑÑкÑв Ñ ÑиÑоко поÑиÑÐµÐ½Ð¾Ñ ÑеÑ
нÑкоÑ: ÑÑнкÑÑÑ Ð¾Ð±ÑоблÑÑ Ð²Ð¸Ð½ÑÑки низÑкого ÑÑÐ²Ð½Ñ Ñ ÑÑвоÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ виÑого ÑÑÐ²Ð½Ñ Ð·Ð°Ð¼ÑÑÑÑ ÑÑзноманÑÑниÑ
низÑкоÑÑвневиÑ
. ÐинÑÑки низÑкого ÑÑÐ²Ð½Ñ ÑÐ½Ð¾Ð´Ñ ÑÑаÑÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑми ÑÑого обâÑкÑа, напÑиклад,
err.cause, Ñк Ñ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð²Ð¸Ñе пÑÐ¸ÐºÐ»Ð°Ð´Ð°Ñ , але Ñе не Ñ ÑÑвоÑо обовâÑзковим.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)