Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як розширити Error власними властивостями?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Щоб розширити **`Error`** власними властивостями, треба створити свій клас, який успадковується від `Error`, і додати до нього потрібні поля - наприклад, `code`, `status`, `details`, `cause`. **Ключове:** у конструкторі обов'язково викликається `super(message)`, щоб передати повідомлення батьківському класу `Error`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Основна ідея Ти створюєш **власний клас**, який **успадковується від** `Error`, і додаєш до нього потрібні властивості - наприклад: `code`, `status`, `details`, `cause`, `context` тощо. ## 2. Приклад: базова кастомна помилка ```javascript class AppError extends Error { constructor(message, code) { super(message); // передаємо повідомлення батьку (Error) this.name = "AppError"; // задаємо ім'я помилки this.code = code; // додаємо власну властивість } } try { throw new AppError("Щось пішло не так", "SERVER_ERROR"); } catch (e) { console.log(e.name); // AppError console.log(e.message); // Щось пішло не так console.log(e.code); // SERVER_ERROR console.log(e.stack); // Стек викликів } ``` Тепер у твоєї помилки є і стандартні властивості (`message`, `stack`), і кастомні (`code`). ## 3. Приклад: додавання HTTP-коду і контексту Це зручно для API, особливо в NestJS / Express: ```javascript class HttpError extends Error { constructor(message, status = 500, details = {}) { super(message); this.name = this.constructor.name; this.status = status; this.details = details; if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } } throw new HttpError("Користувача не знайдено", 404, { userId: 123 }); ``` При обробці помилки: ```javascript try { throw new HttpError("Користувача не знайдено", 404, { userId: 123 }); } catch (err) { console.log(err.name); // HttpError console.log(err.status); // 404 console.log(err.details); // { userId: 123 } } ``` ## 4. Приклад: ієрархія кастомних помилок Можна побудувати ціле "дерево" помилок: ```javascript class AppError extends Error { constructor(message, code) { super(message); this.name = this.constructor.name; this.code = code; Error.captureStackTrace?.(this, this.constructor); } } class ValidationError extends AppError { constructor(message, field) { super(message, "VALIDATION_ERROR"); this.field = field; } } class AuthError extends AppError { constructor(message = "Unauthorized") { super(message, "AUTH_ERROR"); this.status = 401; } } ``` Використання: ```javascript try { throw new ValidationError("Невірний email", "email"); } catch (err) { if (err instanceof ValidationError) { console.log("Помилка в полі:", err.field); } console.log(err.code); // VALIDATION_ERROR } ``` ## 5. Приклад з `cause` (ES2022+) Сучасний стандарт ECMAScript підтримує властивість `cause`, щоб зберігати **вихідну помилку**, через яку виникла поточна. ```javascript try { JSON.parse("invalid JSON"); } catch (parseErr) { throw new AppError("Помилка під час розбору JSON", "PARSE_ERROR", { cause: parseErr }); } ``` Щоб підтримувати `cause`, потрібно додати його в конструктор: ```javascript class AppError extends Error { constructor(message, code, options = {}) { super(message, options); this.name = this.constructor.name; this.code = code; this.cause = options.cause; } } ``` ## 6. Приклад використання в продакшені (Express / NestJS) ```javascript app.use((err, req, res, next) => { if (err instanceof AppError) { res.status(err.status || 500).json({ error: err.name, message: err.message, code: err.code, details: err.details, }); } else { res.status(500).json({ error: "InternalError", message: "Невідома помилка" }); } }); ``` ## 7. Навіщо розширювати Error | Причина | Приклад | | --- | --- | | Чіткі й зрозумілі повідомлення | `"Email обов'язковий"` замість `"Unexpected token"` | | Структура і типізація | `ValidationError`, `AuthError`, `HttpError` | | Зручність логування | Можна включати `code`, `status`, `details` | | Зберігання вихідної причини | через `cause` | | Зручність відлагодження | Різні типи помилок легко розрізняти в `catch` | ## Підсумок Щоб розширити `Error` власними властивостями: ```javascript class MyError extends Error { constructor(message, customProp) { super(message); this.name = "MyError"; this.customProp = customProp; Error.captureStackTrace?.(this, this.constructor); } } ``` І використовувати: ```javascript throw new MyError("Помилка БД", { query: "SELECT * FROM users" }); ```Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.