← Sandbox SDK / sandbox / 1-0-preview
Ошибки и восстановление
Одни сбои означают, что контейнер так и не начал выполнять вашу работу. Другие означают, что работа могла уже начаться. Для этих случаев нужны разные способы восстановления.
Тот же ID песочницы может позже использовать новый контейнер. Процессы, терминалы и локальные файлы предыдущего контейнера сами по себе не восстанавливаются. См. Жизненный цикл песочницы и Сколько живёт процесс.
Каталог классов: API ошибок. Таблица симптомов: Устранение неполадок.
До того как контейнер начнёт работу
Если контейнер не готов, SDK может выбросить исключение ContainerUnavailableError (CONTAINER_UNAVAILABLE). Операция не была выполнена внутри контейнера.
Это часто происходит при холодном старте, после остановки из-за простоя или во время развертывания.
Контекст ошибки включает retryable: true, reason (например, container_starting), а также необязательный retryAfterMs. Сделайте паузу перед повторной попыткой (используйте retryAfterMs если она задана), затем повторите такую же операцию.
Не применяйте то же правило «always retry» к сбоям, которые возникают после того, как контейнер, возможно, уже начал выполнять задачу.
import { ContainerUnavailableError } from "@cloudflare/sandbox";
try {
const process = await sandbox.exec(["npm", "install"], {
cwd: "/workspace/app",
});
await process.waitForExit();
} catch (error) {
if (error instanceof ContainerUnavailableError) {
// Safe to retry the whole operation after backoff.
}
}import { ContainerUnavailableError } from "@cloudflare/sandbox";
try {
const process = await sandbox.exec(["npm", "install"], {
cwd: "/workspace/app",
});
await process.waitForExit();
} catch (error) {
if (error instanceof ContainerUnavailableError) {
// Safe to retry the whole operation after backoff.
}
}После того как контейнер, возможно, начал выполнение работы
Как только контейнер принял операцию, сбой может оставить частичные результаты: процесс может продолжать работать, файл может существовать, резервное копирование может быть начато.
Контейнер заменён или песочница завершена во время вызова
OperationInterruptedError означает, что контейнер или песочница изменились, пока вызов уже выполнялся. Работа могла быть начата.
Используйте reason и retryable для ошибки (см. API ошибок для полей). Если шаги изменяют состояние, проверьте сандбокс или собственные записи, прежде чем повторно выполнять те же шаги.
SDK потерял связь во время вызова
RPCTransportError означает, что SDK потерял связь с текущим контейнером во время вызова. Следующий вызов может снова успешно выполниться с этим же контейнером.
Это делает не означают, что прерванный вызов ничего не сделал. Прежде чем повторять ту же работу, используйте контрольные точки и шаги, безопасные для повторного выполнения, либо проверяйте состояние. Диагностические kind значения перечислены на API ошибок.
Устаревшие дескрипторы процессов или терминалов
ID процессов и терминалов принадлежат текущий контейнер для ID песочницы. После остановки или замены вызовы через старый хендл выбрасывают StaleProcessHandleError или StaleTerminalHandleError. getProcess, getTerminal, listProcesses, а также listTerminals не запускают контейнер. Они возвращают null или [] когда контейнер не запущен или идентификатор неизвестен в текущем контейнере. Это не является исключением.
Сохраняет задачу (команда, cwd, env, контрольная точка), а не только ID ресурса. Затем запустите новый exec или createTerminal когда старый дескриптор больше недоступен.
Локальные ожидания и прерывания
Тайм-ауты и AbortSignal на output(), waitForExit(), waitForLog(), waitForPort(), а также logs() конец которые только ожидают ответа или передают поток данных. Они не завершают процесс. Отмена вывода терминала не завершает PTY.
Используйте process.kill() или terminal.interrupt() / terminal.terminate() когда вы собираетесь остановить ресурс. Типичные ошибки: ProcessWaitTimeoutError, ProcessAbortedError.
Недопустимые аргументы
Недопустимый cwd или переменные окружения, отсутствующий исполняемый файл и похожие проблемы с запросом завершаются ошибкой, пока вы не измените эти значения. Не повторяйте тот же самый некорректный запрос. Типичные классы: InvalidProcessCwdError, InvalidProcessEnvironmentError, ProcessSpawnFailedError.
Несоответствие Worker и образа контейнера
Некоторые сбои означают, что пакет Worker и образ контейнера не соответствуют друг другу, образ не может запуститься или не удалась настройка связи между Worker и контейнером.
| Сигнал | Ответ |
|---|---|
RuntimeControlProtocolError (например, unsupported-protocol-version, отсутствующие или некорректные метаданные) |
Разверните пакет Worker и образ контейнера из одной и той же @cloudflare/sandbox@next строка. Не смешивайте пакеты preview и stable. |
| Неверный или отсутствующий образ, либо контейнер завершает работу до готовности | Исправление wrangler, образ или entrypoint. Повторный вызов того же приложения не поможет. |
| Ограничения ёмкости аккаунта или региона | Снизьте уровень параллелизма или увеличьте лимиты. См. Лимиты платформы. |
Сведения о каталоге: Несоответствие Worker и образа контейнера.
Это не то же самое, что медленный запуск (ContainerUnavailableError). Не используйте один и тот же цикл повторов с задержкой для обоих случаев.
Частые способы восстановления
Первое использование или пробуждение после простоя
Ошибка: ContainerUnavailableError
Сделайте паузу, а затем выполните весь блок работы заново (например, настройку и exec), а не произвольный промежуточный шаг без контрольной точки.
Длительная задача в рамках нескольких запросов Worker
- Сохраните задание и контрольную точку (а также ID процесса или терминала, пока это полезно).
- При последующем запросе вызовите
getProcessилиgetTerminalесли у вас всё ещё есть ID. - Если вы получили дескриптор, продолжайте работу (логи, подключение, ожидание).
- Если вы получаете
nullили ошибку устаревшего дескриптора, начните заново с контрольной точки. - Если вы получаете
ContainerUnavailableError, подождите и продолжите с новой операцией.
Развёртывание или замена во время выполнения вызова
Ошибка: OperationInterruptedError
Прочитайте reason и retryable. Если вызов мог что-то изменить, проверьте состояние перед его повторением.
Потеря связи во время вызова
Ошибка: RPCTransportError
Журнал kind если вам нужна диагностика. Считайте, что незавершённая работа могла быть выполнена. Продолжайте с контрольных точек или проверки, а затем запускайте новую операцию, если задача всё ещё требуется.
Вы просто перестали ждать
Ошибки: ProcessWaitTimeoutError, ProcessAbortedError
Либо продолжайте наблюдение (getProcess и logs({ since })) или остановите процесс с помощью kill. Не считайте, что процесс завершился только потому, что ожидание закончилось.
Недопустимые аргументы
Ошибки: InvalidProcessCwdError, InvalidProcessEnvironmentError, ProcessSpawnFailedError, и аналогичные
Исправьте путь, окружение или команду (либо файлы в образе, если отсутствует исполняемый файл). Не повторяйте попытку с неизменными значениями.
Несоответствие Worker и образа контейнера
Ситуация: После развертывания вызовы завершаются ошибками протокола или настройки, либо контейнер так и не становится пригодным для использования.
Ошибки / сигналы: RuntimeControlProtocolError; неверный образ; контейнер завершает работу до готовности
Можно: Разверните заново пакет Worker и образ контейнера из того же @cloudflare/sandbox@next строка. Проверьте имя образа и entrypoint.
Нельзя: Расценивайте это как медленный запуск контейнера и просто подождите перед повторной попыткой.
Пример
import {
ContainerUnavailableError,
OperationInterruptedError,
RPCTransportError,
StaleProcessHandleError,
ProcessWaitTimeoutError,
ProcessAbortedError,
} from "@cloudflare/sandbox";
try {
const process = await sandbox.exec(["npm", "test"], {
cwd: "/workspace/app",
});
const result = await process.output({ encoding: "utf8" });
console.log(result.exitCode, result.stdout);
} catch (error) {
if (error instanceof ContainerUnavailableError) {
// Container never started the work — back off, then try the work again.
} else if (error instanceof StaleProcessHandleError) {
// Previous container — start again from what you stored about the work.
} else if (error instanceof OperationInterruptedError) {
// Work may have started — read reason/retryable and check state before repeating.
} else if (error instanceof RPCTransportError) {
// Lost contact during the call — a later call may work; this call may already have run.
} else if (
error instanceof ProcessWaitTimeoutError ||
error instanceof ProcessAbortedError
) {
// Wait ended only — process may still be running.
} else {
throw error;
}
}import {
ContainerUnavailableError,
OperationInterruptedError,
RPCTransportError,
StaleProcessHandleError,
ProcessWaitTimeoutError,
ProcessAbortedError,
} from "@cloudflare/sandbox";
try {
const process = await sandbox.exec(["npm", "test"], {
cwd: "/workspace/app",
});
const result = await process.output({ encoding: "utf8" });
console.log(result.exitCode, result.stdout);
} catch (error) {
if (error instanceof ContainerUnavailableError) {
// Container never started the work — back off, then try the work again.
} else if (error instanceof StaleProcessHandleError) {
// Previous container — start again from what you stored about the work.
} else if (error instanceof OperationInterruptedError) {
// Work may have started — read reason/retryable and check state before repeating.
} else if (error instanceof RPCTransportError) {
// Lost contact during the call — a later call may work; this call may already have run.
} else if (
error instanceof ProcessWaitTimeoutError ||
error instanceof ProcessAbortedError
) {
// Wait ended only — process may still be running.
} else {
throw error;
}
}Предпочитайте instanceof с классами из @cloudflare/sandbox. Полные таблицы: API ошибок.