, , , . 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, , ,ValidationErrorSyntaxError,ReadError. -
ReadErrorcause.
, 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.namesuper. -
instanceof. . , , .name. - : . , ,
err.cause, , .
<code>,<pre>, 10 (plnkr, jsbin, codepen)