Обязательноjavascripttypescript

Результаты и ошибки Promise

У каждой асинхронной операции должен быть владелец результата: await, возврат Promise вызывающему коду или явный обработчик отказа у фоновой операции.

Опубликовано Проверено Изменено

Плохо

export function startSave(save: () => Promise<void>): string {
  void save();
  return 'saved';
}

Хорошо

export type SaveResult = { status: 'saved' } | { status: 'failed'; cause: unknown };
export async function saveWithResult(save: () => Promise<void>): Promise<SaveResult> {
  try {
    await save();
    return { status: 'saved' };
  } catch (cause: unknown) {
    return { status: 'failed', cause };
  }
}

Почему это важно

Отложенный отказ не должен становиться ложным сообщением об успехе или неуправляемой ошибкой процесса.

Когда применять

Для JS/TS Promise API. Пример возвращает внутренний результат; вызывающий код обязан разобрать status, а cause нельзя без очистки выводить пользователю или в журнал. Допустима и передача rejected Promise вызывающему слою, если там явно определен обработчик. Это правило не требует превращать каждую ошибку в Result-объект.

Подробные условия

Успех показывается после подтвержденного результата. void promise только отбрасывает значение; rejection остается необработанным, если никто его не принимает.

Обработчик различает отказ и успех и выполняет нужное освобождение ресурсов. Не скрывай ошибку пустым catch. Для deliberate background operation обоснуй, почему завершение вызывающей функции допустимо раньше, кто обрабатывает отказ и что происходит при завершении процесса. Линтер no-floating-promises помогает найти пропуск, но его настройки не доказывают runtime-корректность.

Кто что делает

Человек

Определяет допустимую фоновую работу и видимый результат отказа.

AI-агент

Проверяет владельца каждого Promise, различает deliberate background и забытый await; не подавляет предупреждение без обработки.

Как проверить у себя

  • save выполняется успешно с задержкой → await saveWithResult → saved появляется только после завершения.
  • save отклоняет Promise → дождаться результата → failed с cause, ложного saved нет.
  • Фоновый вызов помечен void → проверить путь отказа и завершение процесса → один void не считается обработкой или гарантией доставки.
Первоисточники
История изменений на GitHub

Дата проверки отражает содержательную сверку. Синхронизация сайта не обновляет её автоматически.