fixes
This commit is contained in:
parent
c4593f1a60
commit
c92f626701
6 changed files with 18 additions and 16 deletions
|
@ -6,7 +6,7 @@ Our errors should support basic error properties like `message`, `name` and, pre
|
|||
|
||||
JavaScript allows to use `throw` with any argument, so technically our custom error classes don't need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error` to identify error objects. So it's better to inherit from it.
|
||||
|
||||
As we build our application, our own errors naturally form a hierarchy, for instance `HttpTimeoutError` may inherit from `HttpError`, and so on.
|
||||
As the application grows, our own errors naturally form a hierarchy, for instance `HttpTimeoutError` may inherit from `HttpError`, and so on.
|
||||
|
||||
## Extending Error
|
||||
|
||||
|
@ -126,7 +126,7 @@ We could also look at `err.name`, like this:
|
|||
|
||||
The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
|
||||
|
||||
Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or such) should fall through.
|
||||
Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.
|
||||
|
||||
## Further inheritance
|
||||
|
||||
|
@ -185,7 +185,7 @@ try {
|
|||
|
||||
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.
|
||||
|
||||
Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = <class name>` when creating each custom error. 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 the constructor. And then inherit from it.
|
||||
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.
|
||||
|
||||
Let's call it `MyError`.
|
||||
|
||||
|
@ -218,7 +218,7 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
|
|||
|
||||
## Wrapping exceptions
|
||||
|
||||
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: the new code will probably generate other kinds of errors.
|
||||
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.
|
||||
|
||||
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`?
|
||||
|
||||
|
@ -303,5 +303,5 @@ The approach is called "wrapping exceptions", because we take "low level excepti
|
|||
## Summary
|
||||
|
||||
- We can inherit from `Error` and other built-in error classes normally, just need to take care of `name` property and don't forget to call `super`.
|
||||
- Most of the time, we should use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks.
|
||||
- Wrapping exceptions is a widespread technique when a function handles low-level exceptions and makes a higher-level object to report about the errors. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required.
|
||||
- We can use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from the 3rd-party library and there's no easy way to get the class. Then `name` property can be used for such checks.
|
||||
- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required.
|
||||
|
|
|
@ -32,6 +32,8 @@ For instance:
|
|||
- `wheel` event -- a mouse wheel roll (a "scrolling" touchpad action generates it too).
|
||||
- `keydown` event for `key:pageUp` and `key:pageDown`.
|
||||
|
||||
Sometimes that may help. But there are more ways to scroll, so it's quite hard to handle all of them. So it's more reliable to use CSS to make something unscrollable, like `overflow` property.
|
||||
If we add an event handler to these events and `event.preventDefault()` in it, then the scroll won't start.
|
||||
|
||||
Sometimes that may help, but it's more reliable to use CSS to make something unscrollable, such as the `overflow` property.
|
||||
|
||||
Here are few tasks that you can solve or look through to see the applications on `onscroll`.
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
|
||||
Opening tag is `pattern:\[(b|url|quote)\]`.
|
||||
|
||||
Then to find everything till the closing tag -- let's the pattern `pattern:[\s\S]*?` to match any character including the newline and then a backreference to the closing tag.
|
||||
Then to find everything till the closing tag -- let's use the pattern `pattern:.*?` with flag `s` to match any character including the newline and then add a backreference to the closing tag.
|
||||
|
||||
The full pattern: `pattern:\[(b|url|quote)\][\s\S]*?\[/\1\]`.
|
||||
The full pattern: `pattern:\[(b|url|quote)\].*?\[/\1\]`.
|
||||
|
||||
In action:
|
||||
|
||||
```js run
|
||||
let reg = /\[(b|url|quote)\][\s\S]*?\[\/\1\]/g;
|
||||
let reg = /\[(b|url|quote)\].*?\[\/\1\]/gs;
|
||||
|
||||
let str = `
|
||||
[b]hello![/b]
|
||||
|
|
|
@ -32,7 +32,7 @@ Create a regexp to find all BB-tags with their contents.
|
|||
For instance:
|
||||
|
||||
```js
|
||||
let reg = /your regexp/g;
|
||||
let reg = /your regexp/flags;
|
||||
|
||||
let str = "..[url]http://google.com[/url]..";
|
||||
alert( str.match(reg) ); // [url]http://google.com[/url]
|
||||
|
@ -41,7 +41,7 @@ alert( str.match(reg) ); // [url]http://google.com[/url]
|
|||
If tags are nested, then we need the outer tag (if we want we can continue the search in its content):
|
||||
|
||||
```js
|
||||
let reg = /your regexp/g;
|
||||
let reg = /your regexp/flags;
|
||||
|
||||
let str = "..[url][b]http://google.com[/b][/url]..";
|
||||
alert( str.match(reg) ); // [url][b]http://google.com[/b][/url]
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
Create a regexp to find strings in double quotes `subject:"..."`.
|
||||
|
||||
The important part is that strings should support escaping, in the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the slash itself as `subject:\\`.
|
||||
The strings should support escaping, the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the slash itself as `subject:\\`.
|
||||
|
||||
```js
|
||||
let str = "Just like \"here\".";
|
||||
```
|
||||
|
||||
For us it's important that an escaped quote `subject:\"` does not end a string.
|
||||
Please note, in particular, that an escaped quote `subject:\"` does not end a string.
|
||||
|
||||
So we should look from one quote to the other ignoring escaped quotes on the way.
|
||||
So we should search from one quote to the other ignoring escaped quotes on the way.
|
||||
|
||||
That's the essential part of the task, otherwise it would be trivial.
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ To separate a part of the pattern for alternation we usually enclose it in paren
|
|||
|
||||
## Regexp for time
|
||||
|
||||
In previous chapters there was a task to build a regexp for searching time in the form `hh:mm`, for instance `12:00`. But a simple `pattern:\d\d:\d\d` is too vague. It accepts `25:99` as the time (99 seconds is valid, but shouldn't be).
|
||||
In previous chapters there was a task to build a regexp for searching time in the form `hh:mm`, for instance `12:00`. But a simple `pattern:\d\d:\d\d` is too vague. It accepts `25:99` as the time (as 99 seconds match the pattern).
|
||||
|
||||
How can we make a better one?
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue