Перейти к содержимому

Таймауты и отмена

Третий аргумент send ограничивает ожидание ответа. Без него промис, на который хост не ответил, не завершается никогда.

import bridge from "@vkma.dev/bridge";
await bridge.send("VKWebAppGetUserInfo", undefined, {
timeout: 5000,
signal: controller.signal,
});
Опция Тип Эффект
timeout number Реджект через N миллисекунд без ответа
signal AbortSignal Реджект в момент abort()

Обе опции независимы, работают вместе или по одной.

Реджект — Error с именем TimeoutError и сообщением вида VK Bridge send "VKWebAppGetUserInfo" timed out after 5000ms:

try {
await bridge.send("VKWebAppGetUserInfo", undefined, { timeout: 5000 });
} catch (error) {
if (error instanceof Error && error.name === "TimeoutError") {
// хост не ответил за 5 секунд
}
}

Отмена через AbortController — закрывай бокс, уводишь пользователя с экрана, теряешь сеть:

const controller = new AbortController();
const user = bridge.send("VKWebAppGetUserInfo", undefined, { signal: controller.signal });
controller.abort(); // промис реджектится сразу

Реджект — Error с именем AbortError. Уже абортнутый сигнал отклоняет вызов до отправки: ни записи в транспорт, ни записи в tap — вызова как бы не было.

timeout и abort срабатывают даже для непарных вызовов (например, inject: false без своего request_id). После реджекта слот ожидания свободен: когда ответ всё же приезжает, промис уже завершён, и ответ приходит как обычное событие — в subscribe и в tap с kind: "event". Двойного реджекта не будет.

Встроенных retry нет — промис честно заканчивается на первом исходе. Оберни сам:

import bridge, { type UserInfo } from "@vkma.dev/bridge";
async function getUserInfoWithRetry(attempts = 2): Promise<UserInfo> {
for (let i = 0; i <= attempts; i++) {
try {
return await bridge.send("VKWebAppGetUserInfo", undefined, { timeout: 3000 });
} catch (error) {
if (i === attempts || (error instanceof Error && error.name === "AbortError")) {
throw error;
}
}
}
throw new Error("unreachable");
}

Учитывай, что хост мог получить и выполнить первый вызов — повтор выполняет метод повторно. Для неидемпотентных методов (платежи, посты) решай на стороне хоста, а не повторами.