Ðогда ÑÑо-Ñо ÑазÑабаÑÑваем, Ñо нам ÑаÑÑо необÑ
Ð¾Ð´Ð¸Ð¼Ñ ÑобÑÑвеннÑе клаÑÑÑ Ð¾Ñибок Ð´Ð»Ñ ÑазнÑÑ
веÑей, коÑоÑÑе могÑÑ Ð¿Ð¾Ð¹Ñи не Ñак в наÑиÑ
задаÑаÑ
. ÐÐ»Ñ Ð¾Ñибок пÑи ÑабоÑе Ñ ÑеÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð½Ð°Ð´Ð¾Ð±Ð¸ÑÑÑÑ 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": "John", "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 = <ÑÑек вÑзовов>; // неÑÑандаÑÑное ÑвойÑÑво, но обÑÑно поддеÑживаеÑÑÑ
}
}
ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе ÑнаÑледÑем Ð¾Ñ Ð½ÐµÐ³Ð¾ 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";
}
}
// ÐÑполÑзование
function readUser(json) {
let user = JSON.parse(json);
if (!user.age) {
throw new ValidationError("ÐÐµÑ Ð¿Ð¾Ð»Ñ: age");
}
if (!user.name) {
throw new ValidationError("ÐÐµÑ Ð¿Ð¾Ð»Ñ: name");
}
return user;
}
// РабоÑий пÑÐ¸Ð¼ÐµÑ Ñ try..catch
try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
alert("ÐекоÑÑекÑнÑе даннÑе: " + err.message); // ÐекоÑÑекÑнÑе даннÑе: ÐÐµÑ Ð¿Ð¾Ð»Ñ: name
} else if (err instanceof SyntaxError) { // (*)
alert("JSON ÐÑибка СинÑакÑиÑа: " + 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("ÐÐµÑ ÑвойÑÑва: " + 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 = <class 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 = ..." в конÑÑÑÑкÑоÑе.
ÐбÑÑÑÑвание иÑклÑÑений
ÐазнаÑение ÑÑнкÑии 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, коÑоÑÑй ÑвлÑеÑÑÑ Ð±Ð¾Ð»ÐµÐµ абÑÑÑакÑнÑм и более ÑдобнÑм Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² вÑзÑваÑÑем коде. Такой подÑ
од ÑиÑоко иÑполÑзÑеÑÑÑ Ð² обÑекÑно-оÑиенÑиÑованном пÑогÑаммиÑовании.
ÐÑого
- ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ наÑледоваÑÑ Ñвои клаÑÑÑ Ð¾Ñибок оÑ
Errorи дÑÑÐ³Ð¸Ñ Ð²ÑÑÑоеннÑÑ ÐºÐ»Ð°ÑÑов оÑибок, но нÑжно позабоÑиÑÑÑÑ Ð¾ ÑвойÑÑвеnameи не забÑÑÑ Ð²ÑзваÑÑsuper. - ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ иÑполÑзоваÑÑ
instanceofÐ´Ð»Ñ Ð¿ÑовеÑки Ñипа оÑибок. ÐÑо Ñакже ÑабоÑÐ°ÐµÑ Ñ Ð½Ð°Ñледованием. Ðо иногда Ñ Ð½Ð°Ñ Ð¾Ð±ÑÐµÐºÑ Ð¾Ñибки, возникÑей в ÑÑоÑонней библиоÑеке, и Ð½ÐµÑ Ð¿ÑоÑÑого ÑпоÑоба полÑÑиÑÑ ÐºÐ»Ð°ÑÑ. Тогда Ð´Ð»Ñ Ð¿ÑовеÑки Ñипа оÑибки можно иÑполÑзоваÑÑ ÑвойÑÑвоname. - ÐбÑÑÑÑвание иÑклÑÑений ÑвлÑеÑÑÑ ÑаÑпÑоÑÑÑанÑнной ÑеÑ
никой: ÑÑнкÑÐ¸Ñ Ð»Ð¾Ð²Ð¸Ñ Ð½Ð¸Ð·ÐºÐ¾ÑÑовневÑе иÑклÑÑÐµÐ½Ð¸Ñ Ð¸ ÑоздаÑÑ Ð¾Ð´Ð½Ð¾ «вÑÑокоÑÑовневое» иÑклÑÑение вмеÑÑо ÑазнÑÑ
низкоÑÑовневÑÑ
. Ðногда низкоÑÑовневÑе иÑклÑÑÐµÐ½Ð¸Ñ ÑÑановÑÑÑÑ ÑвойÑÑвами ÑÑого обÑекÑа, как
err.causeв пÑимеÑÐ°Ñ Ð²ÑÑе, но ÑÑо не обÑзаÑелÑно.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)