Результаты и ошибки 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 не считается обработкой или гарантией доставки.
Первоисточники
- typescript-eslint: no-floating-promises — Handled promises; void does not handle rejection.
Дата проверки отражает содержательную сверку. Синхронизация сайта не обновляет её автоматически.