Skip to content

Commit 6700835

Browse files
committed
closes #1808
1 parent a11cc18 commit 6700835

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

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

+32-4
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,39 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
215215
216216
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.
217217
218-
The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. But if the `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`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones.
219219
220-
Often the answer is "No": the outer code wants to be "one level above all that", it just wants to have some kind of "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, it could have a way to get the error details, but only if we need to.
220+
The scheme is like this:
221221
222-
So let's make a new class `ReadError` to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in its `cause` property. Then the outer code will only have to check for `ReadError`.
222+
```js
223+
try {
224+
...
225+
readUser() // the potential error source
226+
...
227+
} catch (err) {
228+
if (err instanceof ValidationError) {
229+
// handle validation errors
230+
} else if (err instanceof SyntaxError) {
231+
// handle syntax errors
232+
} else {
233+
throw err; // unknown error, rethrow it
234+
}
235+
}
236+
```
237+
238+
In the code above we can see two types of errors, but there can be more.
239+
240+
If the `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 every time?
241+
242+
Often the answer is "No": we'd like to be "one level above all that". We just want to know if there was a "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, we'd like to have a way to get the error details, but only if we need to.
243+
244+
The technique that we describe here is called "wrapping exceptions".
245+
246+
1. We'll make a new class `ReadError` to represent a generic "data reading" error.
247+
2. The function `readUser` will catch data reading errors that occur inside it, such as `ValidationError` and `SyntaxError`, and generate `ReadError` instead.
248+
3. The `ReadError` object will keep the reference to the original error in its `cause` property.
249+
250+
Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors.
223251
224252
Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`:
225253
@@ -293,7 +321,7 @@ In the code above, `readUser` works exactly as described -- catches syntax and v
293321
294322
So the outer code checks `instanceof ReadError` and that's it. No need to list all possible error types.
295323
296-
The approach is called "wrapping exceptions", because we take "low level exceptions" and "wrap" them into `ReadError` that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming.
324+
The approach is called "wrapping exceptions", because we take "low level" exceptions and "wrap" them into `ReadError` that is more abstract. It is widely used in object-oriented programming.
297325
298326
## Summary
299327

0 commit comments

Comments
 (0)