Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 78fbf95

Browse files
committedAug 6, 2019
minor
1 parent 84ff065 commit 78fbf95

File tree

1 file changed

+9
-14
lines changed

1 file changed

+9
-14
lines changed
 

‎1-js/10-error-handling/2-custom-errors/article.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,26 @@ Here's an example of how a valid `json` may look:
1717
let json = `{ "name": "John", "age": 30 }`;
1818
```
1919

20-
Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it throws `SyntaxError`.
21-
22-
But even if `json` is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, it may not have `name` and `age` properties that are essential for our users.
20+
Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it throws `SyntaxError`. But even if `json` is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, it may not have `name` and `age` properties that are essential for our users.
2321

2422
Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field.
2523

2624
Our `ValidationError` class should inherit from the built-in `Error` class.
2725

28-
That class is built-in, but we should have its approximate code before our eyes, to understand what we're extending.
29-
30-
So here you are:
26+
That class is built-in, here's it approximate code, for us to understand what we're extending:
3127

3228
```js
3329
// The "pseudocode" for the built-in Error class defined by JavaScript itself
3430
class Error {
3531
constructor(message) {
3632
this.message = message;
3733
this.name = "Error"; // (different names for different built-in error classes)
38-
this.stack = <nested calls>; // non-standard, but most environments support it
34+
this.stack = <call stack>; // non-standard, but most environments support it
3935
}
4036
}
4137
```
4238

43-
Now let's go on and inherit `ValidationError` from it:
39+
Now let's inherit `ValidationError` from it and try it in action:
4440

4541
```js run untrusted
4642
*!*
@@ -65,10 +61,9 @@ try {
6561
}
6662
```
6763

68-
Please take a look at the constructor:
64+
Please note: in the line `(1)` we call the parent constructor. JavaScript requires us to call `super` in the child constructor, so that's obligatory. The parent constructor sets the `message` property.
6965

70-
1. In the line `(1)` we call the parent constructor. JavaScript requires us to call `super` in the child constructor, so that's obligatory. The parent constructor sets the `message` property.
71-
2. The parent constructor also sets the `name` property to `"Error"`, so in the line `(2)` we reset it to the right value.
66+
The parent constructor also sets the `name` property to `"Error"`, so in the line `(2)` we reset it to the right value.
7267

7368
Let's try to use it in `readUser(json)`:
7469

@@ -185,7 +180,7 @@ try {
185180
186181
The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(property)`. The human-readable `message` is generated by the constructor.
187182
188-
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` in every custom error class. But there's a way out. We can make our own "basic error" class that removes this burden from our shoulders by using `this.constructor.name` for `this.name` in its constructor. And then inherit all ours custom errors from it.
183+
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name = this.constructor.name`. And then inherit all ours custom errors from it.
189184
190185
Let's call it `MyError`.
191186
@@ -218,9 +213,9 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
218213
219214
## Wrapping exceptions
220215
221-
The purpose of the function `readUser` in the code above is "to read the user data", right? There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow and probably generate other kinds of errors.
216+
The purpose of the function `readUser` in the code above is "to read the user data". There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow and probably generate other kinds of errors.
222217
223-
The code which calls `readUser` should handle these errors. Right now it uses multiple `if` in the `catch` block to check for different error types and rethrow the unknown ones. But if `readUser` function generates several kinds of errors -- then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`?
218+
The code which calls `readUser` should handle these errors. Right now it uses multiple `if` in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. But if `readUser` function generates several kinds of errors -- then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`?
224219
225220
Often the answer is "No": the outer code wants to be "one level above all that". It wants to have some kind of "data reading error". Why exactly it happened -- is often irrelevant (the error message describes it). Or, even better if there is a way to get error details, but only if we need to.
226221

0 commit comments

Comments
 (0)
Please sign in to comment.