Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про TypeScript: custom, error, handling

Можно ли создать собственный тип ошибки (custom error type)? Как?

Этот вопрос проверяет знание создания специализированных типов ошибок в TypeScript и понимание наследования встроенного класса Error.

Короткий ответ

Да, можно создать собственный тип ошибки. Для этого нужно создать класс, который наследуется от встроенного класса Error, и добавить необходимые свойства и методы. В конструкторе обязательно нужно вызвать super() и установить Object.setPrototypeOf(this, CustomError.prototype) для правильной работы instanceof.

Длинный ответ

Создание пользовательских типов ошибок

Собственные типы ошибок позволяют создавать специализированные исключения с дополнительной информацией.

Базовый пользовательский класс ошибки

typescript

class CustomError extends Error {
  constructor(message: string) {
    super(message);
    
    // Важно для правильной работы instanceof
    Object.setPrototypeOf(this, CustomError.prototype);
    
    // Сохраняем стек вызовов
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, CustomError);
    }
    
    this.name = "CustomError";
  }
}

Специализированные ошибки с дополнительными свойствами

typescript

class ValidationError extends Error {
  public readonly field: string;
  public readonly value: any;

  constructor(field: string, value: any, message?: string) {
    super(message || `Ошибка валидации поля ${field}`);
    
    this.name = "ValidationError";
    this.field = field;
    this.value = value;
    
    Object.setPrototypeOf(this, ValidationError.prototype);
  }
}

class NetworkError extends Error {
  public readonly statusCode: number;
  public readonly url: string;

  constructor(statusCode: number, url: string, message?: string) {
    super(message || `Сетевая ошибка ${statusCode} для ${url}`);
    
    this.name = "NetworkError";
    this.statusCode = statusCode;
    this.url = url;
    
    Object.setPrototypeOf(this, NetworkError.prototype);
  }
}

Использование пользовательских ошибок

typescript

function validateUser(user: any): void {
  if (!user.name) {
    throw new ValidationError("name", user.name, "Имя обязательно");
  }
  
  if (user.age < 0) {
    throw new ValidationError("age", user.age, "Возраст не может быть отрицательным");
  }
}

function fetchUser(id: number): Promise<User> {
  return fetch(`/api/users/${id}`)
    .then(response => {
      if (!response.ok) {
        throw new NetworkError(response.status, `/api/users/${id}`);
      }
      return response.json();
    });
}

Обработка пользовательских ошибок

typescript

try {
  validateUser({ age: -1 });
} catch (error) {
  if (error instanceof ValidationError) {
    console.error(`Ошибка в поле ${error.field}:`, error.message);
    // Ошибка в поле age: Возраст не может быть отрицательным
  } else {
    console.error("Неизвестная ошибка:", error);
  }
}

Иерархия ошибок

Можно создавать сложные иерархии ошибок:

typescript

abstract class AppError extends Error {
  public abstract readonly code: string;
  
  constructor(message: string) {
    super(message);
    this.name = this.constructor.name;
    Object.setPrototypeOf(this, new.target.prototype);
  }
}

class DatabaseError extends AppError {
  public readonly code = "DB_ERROR";
  public readonly query: string;

  constructor(query: string, message: string) {
    super(message);
    this.query = query;
  }
}

class UniqueConstraintError extends DatabaseError {
  public readonly code = "UNIQUE_CONSTRAINT";
  public readonly constraint: string;

  constructor(constraint: string, query: string) {
    super(query, `Нарушено ограничение уникальности: ${constraint}`);
    this.constraint = constraint;
  }
}

Практические рекомендации

1. Всегда устанавливайте прототип

typescript

// Без этого instanceof не будет работать правильно
Object.setPrototypeOf(this, CustomError.prototype);

2. Используйте правильное имя

typescript

this.name = this.constructor.name; // Автоматически устанавливает имя

3. Добавляйте код ошибки

typescript

class BusinessError extends Error {
  public readonly code: string;
  
  constructor(code: string, message: string) {
    super(message);
    this.code = code;
    this.name = "BusinessError";
    Object.setPrototypeOf(this, BusinessError.prototype);
  }
}

Вывод: Создание пользовательских типов ошибок позволяет структурировать обработку исключений, добавлять контекстную информацию и создавать понятную иерархию ошибок для лучшего управления ошибками в приложении.

Уровень

  • Рейтинг:

    3

  • Сложность:

    5

Навыки

  • TypeScript

    TypeScript

Ключевые слова

#custom

#error

#handling

Подпишись на React Developer в телеграм