# Exception Handling

Обробка винятків.

JavaScript має клас `Error`, який можна використовувати для винятків. Ви видаєте помилку з ключовим словом `throw`. Ви можете зловити його за допомогою пари блоків `try` / `catch`, наприклад.

```js
try {
  throw new Error('Something bad happened');
}
catch(e) {
  console.log(e);
}
```

## Error Sub Types

Подтипи помилок.

Окрім вбудованого класу `Error`, є кілька додаткових вбудованих класів помилок, які успадковують від `Error`, які може викликати середовище виконання JavaScript:

### RangeError

Створює екземпляр, що представляє помилку, яка виникає, коли числова змінна або параметр виходить за межі допустимого діапазону.

```js
// Виклик з перевіщенною кількістю аргументів
console.log.apply(console, new Array(1000000000)); // RangeError: Недійсна довжина масиву
```

### ReferenceError

Створює екземпляр, що представляє помилку, яка виникає під час використання недійсного посилання. Наприкллад:

```js
'use strict';
console.log(notValidVar); // ReferenceError: notValidVar не визначено
```

### SyntaxError

Створює екземпляр, що представляє синтаксичну помилку, яка виникає під час аналізу коду, який не є дійсним JavaScript.

```js
1***3; // SyntaxError: Несподіваний маркер *
```

### TypeError

Створює екземпляр, що представляє помилку, яка виникає, коли змінна або параметр має недійсний тип.

```js
('1.2').toPrecision(1); // TypeError: '1.2'.toPrecision не є функцією
```

### URIError

Створює екземпляр, що представляє помилку, яка виникає, коли `encodeURI()` або `decodeURI()` передають недійсні параметри.

```js
decodeURI('%'); // URIError: неправильний URI
```

## Always use `Error`

Початківці розробники JavaScript іноді просто кидають необроблені рядки, наприклад.

```js
try {
  throw 'Something bad happened';
}
catch(e) {
  console.log(e);
}
```

*Don't do that*. Фундаментальна перевага об’єктів `Error` полягає в тому, що вони автоматично відстежують, де вони були створені та що іх викликало за допомогою властивості `stack`.

Необроблені рядки призводять до дуже болісного досвіду налагодження та ускладнюють аналіз помилок із журналів.

## You don't have to `throw` an error

Передавати об’єкт `Error` можна. Це традиційно для коду стилю зворотного виклику Node.js, який приймає зворотні виклики з першим аргументом як об’єкт помилки.

```js
function myFunction (callback: (e?: Error)) {
  doSomethingAsync(function () {
    if (somethingWrong) {
      callback(new Error('This is my error'))
    } else {
      callback();
    }
  });
}
```

## Exceptional cases

`Exceptions should be exceptional`(Винятки мають бути винятковими) — загальний вислів у інформатиці. Є кілька причин, чому це також стосується JavaScript (і TypeScript).

### Unclear where it is thrown

Розглянемо такий фрагмент коду:

```js
try {
  const foo = runTask1();
  const bar = runTask2();
}
catch(e) {
  console.log('Error:', e);
}
```

Наступний розробник не може знати, яка функція може викликати помилку. Людина, яка переглядає код, не може знати, не прочитавши код для task1 / task2 та інших функцій, які вони можуть викликати тощо.

### Makes graceful handling hard

Ви можете спробувати зробити це витонченим, чітко зафіксувавши кожну річ, яка може викинути:

```js
try {
  const foo = runTask1();
}
catch(e) {
  console.log('Error:', e);
}
try {
  const bar = runTask2();
}
catch(e) {
  console.log('Error:', e);
}
```

Але тепер, якщо вам потрібно передати матеріали з першого завдання до другого, код стає безладним: (зверніть увагу на мутацію `foo`, що вимагає `let` + явну потребу анотувати це, оскільки це не можна вивести з повернення `runTask1`) :

```ts
let foo: number; // Notice use of `let` and explicit type annotation
try {
  foo = runTask1();
}
catch(e) {
  console.log('Error:', e);
}
try {
  const bar = runTask2(foo);
}
catch(e) {
  console.log('Error:', e);
}
```

### Not well represented in the type system

Розглянемо функцію:

```ts
function validate(value: number) {
  if (value < 0 || value > 100) throw new Error('Invalid value');
}
```

Використання `Error` для таких випадків є поганою ідеєю, оскільки воно не представлено у визначенні типу для функції перевірки (це `(value:number) => void`). Натомість кращим способом створення методу перевірки буде:

```ts
function validate(value: number): {error?: string} {
  if (value < 0 || value > 100) return {error:'Invalid value'};
}
```

А тепер його представлено в системі типів.

> Якщо ви не хочете обробити помилку дуже загальним (простим/всеохоплюючим тощо), не *генеруйте* помилку.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://artfulbits-se.gitbook.io/typescript/type-system/exceptions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
