|
1 | | -# Exception Handling |
| 1 | +# Обработка исключений |
2 | 2 |
|
3 | | -JavaScript has an `Error` class that you can use for exceptions. You throw an error with the `throw` keyword. You can catch it with a `try` / `catch` block pair e.g. |
| 3 | +В JavaScript есть класс `Error`, который можно использовать для исключений. Вы выбрасываете ошибку с ключевым словом `throw`. Вы можете отловить её с помощью блоков `try` / `catch`, например: |
4 | 4 |
|
5 | 5 | ```js |
6 | 6 | try { |
7 | | - throw new Error('Something bad happened'); |
| 7 | + throw new Error('Случилось что-то плохое'); |
8 | 8 | } |
9 | 9 | catch(e) { |
10 | 10 | console.log(e); |
11 | 11 | } |
12 | 12 | ``` |
13 | 13 |
|
14 | | -## Error Sub Types |
| 14 | +## Подтипы ошибок |
15 | 15 |
|
16 | | -Beyond the built in `Error` class there are a few additional built-in error classes that inherit from `Error` that the JavaScript runtime can throw: |
| 16 | +Помимо встроенного класса `Error`, существует несколько дополнительных встроенных классов ошибок, которые наследуются от `Error`, которые может генерировать среда выполнения JavaScript: |
17 | 17 |
|
18 | 18 | ### RangeError |
19 | 19 |
|
20 | | -Creates an instance representing an error that occurs when a numeric variable or parameter is outside of its valid range. |
| 20 | +Создается экземпляр ошибки, которая возникает, когда числовая переменная или параметр выходит за пределы допустимого диапазона. |
21 | 21 |
|
22 | 22 | ```js |
23 | | -// Call console with too many arguments |
24 | | -console.log.apply(console, new Array(1000000000)); // RangeError: Invalid array length |
| 23 | +// Вызов консоли с слишком большим количеством параметров |
| 24 | +console.log.apply(console, new Array(1000000000)); // RangeError: Невалидная длина массива |
25 | 25 | ``` |
26 | 26 |
|
27 | 27 | ### ReferenceError |
28 | 28 |
|
29 | | -Creates an instance representing an error that occurs when de-referencing an invalid reference. e.g. |
| 29 | +Создается экземпляр ошибки, которая возникает при разыменовании недействительной ссылки. Например: |
30 | 30 |
|
31 | 31 | ```js |
32 | 32 | 'use strict'; |
33 | | -console.log(notValidVar); // ReferenceError: notValidVar is not defined |
| 33 | +console.log(notValidVar); // ReferenceError: notValidVar не определена |
34 | 34 | ``` |
35 | 35 |
|
36 | 36 | ### SyntaxError |
37 | 37 |
|
38 | | -Creates an instance representing a syntax error that occurs while parsing code that isn't valid JavaScript. |
| 38 | +Создается экземпляр ошибки, возникающей при синтаксическом анализе кода, который не является допустимым в JavaScript. |
39 | 39 |
|
40 | 40 | ```js |
41 | | -1***3; // SyntaxError: Unexpected token * |
| 41 | +1***3; // SyntaxError: Непредвиденный токен * |
42 | 42 | ``` |
43 | 43 |
|
44 | 44 | ### TypeError |
45 | 45 |
|
46 | | -Creates an instance representing an error that occurs when a variable or parameter is not of a valid type. |
| 46 | +Создается экземпляр ошибки, которая возникает, когда переменная или параметр имеет недопустимый тип. |
47 | 47 |
|
48 | 48 | ```js |
49 | | -('1.2').toPrecision(1); // TypeError: '1.2'.toPrecision is not a function |
| 49 | +('1.2').toPrecision(1); // TypeError: '1.2'.toPrecision не является функцией |
50 | 50 | ``` |
51 | 51 |
|
52 | 52 | ### URIError |
53 | 53 |
|
54 | | -Creates an instance representing an error that occurs when `encodeURI()` or `decodeURI()` are passed invalid parameters. |
| 54 | +Создается экземпляр ошибки, которая возникает, когда в `encodeURI()` или `decodeURI()` передаются недопустимые параметры. |
55 | 55 |
|
56 | 56 | ```js |
57 | | -decodeURI('%'); // URIError: URI malformed |
| 57 | +decodeURI('%'); // URIError: URI неправильно сформирован |
58 | 58 | ``` |
59 | 59 |
|
60 | | -## Always use `Error` |
| 60 | +## Всегда используйте `Error` |
61 | 61 |
|
62 | | -Beginner JavaScript developers sometimes just throw raw strings e.g. |
| 62 | +Начинающие разработчики JavaScript иногда просто бросают необработанные строки, например. |
63 | 63 |
|
64 | 64 | ```js |
65 | 65 | try { |
66 | | - throw 'Something bad happened'; |
| 66 | + throw 'Случилось что-то плохое'; |
67 | 67 | } |
68 | 68 | catch(e) { |
69 | 69 | console.log(e); |
70 | 70 | } |
71 | 71 | ``` |
72 | 72 |
|
73 | | -*Don't do that*. The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated with the `stack` property. |
| 73 | +*Не делайте так*. Основное преимущество объектов `Error` состоит в том, что автоматически отслеживается где они были созданы и произошли с помощью свойства `stack`. |
74 | 74 |
|
75 | | -Raw strings result in a very painful debugging experience and complicate error analysis from logs. |
| 75 | +Необработанные строки приводят к очень болезненной отладке и затрудняют анализ ошибок из логов. |
76 | 76 |
|
77 | | -## You don't have to `throw` an error |
| 77 | +## Вам не нужно `выбрасывать` ошибку |
78 | 78 |
|
79 | | -It is okay to pass an `Error` object around. This is conventional in Node.js callback style code which takes callbacks with the first argument as an error object. |
| 79 | +Это нормально передавать объект `Error`. Это общепринятый код в Node.js колбэк стиле, который принимает колбэк первым параметром как объект ошибки. |
80 | 80 |
|
81 | 81 | ```js |
82 | 82 | function myFunction (callback: (e?: Error)) { |
83 | 83 | doSomethingAsync(function () { |
84 | 84 | if (somethingWrong) { |
85 | | - callback(new Error('This is my error')) |
| 85 | + callback(new Error('Это моя ошибка')) |
86 | 86 | } else { |
87 | 87 | callback(); |
88 | 88 | } |
89 | 89 | }); |
90 | 90 | } |
91 | 91 | ``` |
92 | 92 |
|
93 | | -## Exceptional cases |
| 93 | +## Исключительные случаи |
94 | 94 |
|
95 | | -`Exceptions should be exceptional` is a common saying in computer science. There are a few reasons why this is true for JavaScript (and TypeScript) as well. |
| 95 | +`Исключения должны быть исключительными` - это частая поговорка в компьютерных науках. Это одинаково справедливо и для JavaScript (и для TypeScript) по нескольким причинам. |
96 | 96 |
|
97 | | -### Unclear where it is thrown |
| 97 | +### Неясно откуда брошено исключение |
98 | 98 |
|
99 | | -Consider the following piece of code: |
| 99 | +Рассмотрим следующий фрагмент кода: |
100 | 100 |
|
101 | 101 | ```js |
102 | 102 | try { |
103 | 103 | const foo = runTask1(); |
104 | 104 | const bar = runTask2(); |
105 | 105 | } |
106 | 106 | catch(e) { |
107 | | - console.log('Error:', e); |
| 107 | + console.log('Ошибка:', e); |
108 | 108 | } |
109 | 109 | ``` |
110 | 110 |
|
111 | | -The next developer cannot know which function might throw the error. The person reviewing the code cannot know without reading the code for task1 / task2 and other functions they might call etc. |
| 111 | +Следующий разработчик не знает, какая функция может вызвать ошибку. Человек, просматривающий код, не может знать об этом, не прочитав код для task1 / task2 и других функций, которые они могут вызвать внутри себя и т.д. |
112 | 112 |
|
113 | | -### Makes graceful handling hard |
| 113 | +### Делает поэтапную обработку сложной |
114 | 114 |
|
115 | | -You can try to make it graceful with explicit catch around each thing that might throw: |
| 115 | +Вы можете попытаться сделать обработку поэтапной с помощью явного отлова вокруг каждого места, которое может бросить ошибку: |
116 | 116 |
|
117 | 117 | ```js |
118 | 118 | try { |
119 | 119 | const foo = runTask1(); |
120 | 120 | } |
121 | 121 | catch(e) { |
122 | | - console.log('Error:', e); |
| 122 | + console.log('Ошибка:', e); |
123 | 123 | } |
124 | 124 | try { |
125 | 125 | const bar = runTask2(); |
126 | 126 | } |
127 | 127 | catch(e) { |
128 | | - console.log('Error:', e); |
| 128 | + console.log('Ошибка:', e); |
129 | 129 | } |
130 | 130 | ``` |
131 | 131 |
|
132 | | -But now if you need to pass stuff from the first task to the second one the code becomes messy: (notice `foo` mutation requiring `let` + explicit need for annotating it because it cannot be inferred from the return of `runTask1`): |
| 132 | +Но теперь, если вам нужно передать что-то из первой задачи во вторую, код становится грязным: (обратите внимание на мутацию `foo`, требующую `let` + явную необходимость описывать ее, потому что это не может быть логически выведено от возврата `runTask1`): |
133 | 133 |
|
134 | 134 | ```ts |
135 | | -let foo: number; // Notice use of `let` and explicit type annotation |
| 135 | +let foo: number; // Обратите внимание на использование `let` и явное описание типа |
136 | 136 | try { |
137 | 137 | foo = runTask1(); |
138 | 138 | } |
139 | 139 | catch(e) { |
140 | | - console.log('Error:', e); |
| 140 | + console.log('Ошибка:', e); |
141 | 141 | } |
142 | 142 | try { |
143 | 143 | const bar = runTask2(foo); |
144 | 144 | } |
145 | 145 | catch(e) { |
146 | | - console.log('Error:', e); |
| 146 | + console.log('Ошибка:', e); |
147 | 147 | } |
148 | 148 | ``` |
149 | 149 |
|
150 | | -### Not well represented in the type system |
| 150 | +### Не очень хорошо отражено в системе типов |
151 | 151 |
|
152 | | -Consider the function: |
| 152 | +Рассмотрим функцию: |
153 | 153 |
|
154 | 154 | ```ts |
155 | 155 | function validate(value: number) { |
156 | | - if (value < 0 || value > 100) throw new Error('Invalid value'); |
| 156 | + if (value < 0 || value > 100) throw new Error('Невалидное значение'); |
157 | 157 | } |
158 | 158 | ``` |
159 | 159 |
|
160 | | -Using `Error` for such cases is a bad idea as it is not represented in the type definition for the validate function (which is `(value:number) => void`). Instead a better way to create a validate method would be: |
| 160 | +Использование `Error` для таких случаев - плохая идея, так как ошибка не отражена в определении типа для проверки функции `(value:number) => void`. Вместо этого лучший способ создать метод проверки: |
161 | 161 |
|
162 | 162 | ```ts |
163 | 163 | function validate(value: number): {error?: string} { |
164 | | - if (value < 0 || value > 100) return {error:'Invalid value'}; |
| 164 | + if (value < 0 || value > 100) return {error:'Невалидное значение'}; |
165 | 165 | } |
166 | 166 | ``` |
167 | 167 |
|
168 | | -And now its represented in the type system. |
| 168 | +И теперь это отражено в системе типов. |
169 | 169 |
|
170 | | -> Unless you want to handle the error in a very generic (simple / catch-all etc) way, don't *throw* an error. |
| 170 | +> Если вы не хотите обрабатывать ошибку очень общим (простым / универсальным и т.д.) способом, не *бросайте* ошибку. |
0 commit comments