Suggest an editImprove this articleRefine the answer for “How to extend Error with custom properties?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)To extend **`Error`** with custom properties, you create your own class that inherits from `Error` and add the fields you need, such as `code`, `status`, `details`, `cause`. **Key point:** the constructor must call `super(message)` to pass the message to the parent `Error` class.Shown above the full answer for quick recall.Answer (EN)Image## 1. The main idea You create **your own class** that **inherits from** `Error`, and add the properties you need to it - for example: `code`, `status`, `details`, `cause`, `context`, and so on. ## 2. Example: a basic custom error ```javascript class AppError extends Error { constructor(message, code) { super(message); // pass the message to the parent (Error) this.name = "AppError"; // set the error's name this.code = code; // add our own property } } try { throw new AppError("Something went wrong", "SERVER_ERROR"); } catch (e) { console.log(e.name); // AppError console.log(e.message); // Something went wrong console.log(e.code); // SERVER_ERROR console.log(e.stack); // Call stack } ``` Now your error has both the standard properties (`message`, `stack`) and custom ones (`code`). ## 3. Example: adding an HTTP code and context This is convenient for APIs, especially in 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("User not found", 404, { userId: 123 }); ``` When handling the error: ```javascript try { throw new HttpError("User not found", 404, { userId: 123 }); } catch (err) { console.log(err.name); // HttpError console.log(err.status); // 404 console.log(err.details); // { userId: 123 } } ``` ## 4. Example: a hierarchy of custom errors You can build a whole "tree" of errors: ```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; } } ``` Usage: ```javascript try { throw new ValidationError("Invalid email", "email"); } catch (err) { if (err instanceof ValidationError) { console.log("Error in field:", err.field); } console.log(err.code); // VALIDATION_ERROR } ``` ## 5. Example with `cause` (ES2022+) The modern ECMAScript standard supports the `cause` property, to store the **original error** that led to the current one. ```javascript try { JSON.parse("invalid JSON"); } catch (parseErr) { throw new AppError("Error parsing JSON", "PARSE_ERROR", { cause: parseErr }); } ``` To support `cause`, you need to add it to the constructor: ```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. Example of usage in production (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: "Unknown error" }); } }); ``` ## 7. Why extend Error | Reason | Example | | --- | --- | | Clear, understandable messages | `"Email is required"` instead of `"Unexpected token"` | | Structure and typing | `ValidationError`, `AuthError`, `HttpError` | | Convenient logging | You can include `code`, `status`, `details` | | Storing the original cause | via `cause` | | Easier debugging | Different error types are easy to tell apart in `catch` | ## Summary To extend `Error` with your own properties: ```javascript class MyError extends Error { constructor(message, customProp) { super(message); this.name = "MyError"; this.customProp = customProp; Error.captureStackTrace?.(this, this.constructor); } } ``` And use it: ```javascript throw new MyError("Database error", { query: "SELECT * FROM users" }); ```For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.