closes #1808
This commit is contained in:
parent
a11cc18d1a
commit
6700835b1f
1 changed files with 32 additions and 4 deletions
|
@ -215,11 +215,39 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
|
|||
|
||||
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.
|
||||
|
||||
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`?
|
||||
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.
|
||||
|
||||
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.
|
||||
The scheme is like this:
|
||||
|
||||
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`.
|
||||
```js
|
||||
try {
|
||||
...
|
||||
readUser() // the potential error source
|
||||
...
|
||||
} catch (err) {
|
||||
if (err instanceof ValidationError) {
|
||||
// handle validation errors
|
||||
} else if (err instanceof SyntaxError) {
|
||||
// handle syntax errors
|
||||
} else {
|
||||
throw err; // unknown error, rethrow it
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the code above we can see two types of errors, but there can be more.
|
||||
|
||||
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?
|
||||
|
||||
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.
|
||||
|
||||
The technique that we describe here is called "wrapping exceptions".
|
||||
|
||||
1. We'll make a new class `ReadError` to represent a generic "data reading" error.
|
||||
2. The function `readUser` will catch data reading errors that occur inside it, such as `ValidationError` and `SyntaxError`, and generate `ReadError` instead.
|
||||
3. The `ReadError` object will keep the reference to the original error in its `cause` property.
|
||||
|
||||
Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors.
|
||||
|
||||
Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`:
|
||||
|
||||
|
@ -293,7 +321,7 @@ In the code above, `readUser` works exactly as described -- catches syntax and v
|
|||
|
||||
So the outer code checks `instanceof ReadError` and that's it. No need to list all possible error types.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Summary
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue