Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

エラーと回復

最終更新 Markdown で表示Agent セットアップ

失敗には、コンテナーが作業を開始していないものと、作業がすでに始まっている可能性があるものがあります。回復の仕方はそれぞれ異なります。

同じ サンドボックス ID でも、あとから 新しいコンテナー を使うことがあります。以前のコンテナーのプロセス、ターミナル、ローカルファイルは、自動では戻りません。Sandbox のライフサイクルプロセスの存続期間 を参照してください。

クラス一覧は Errors API です。症状の表は トラブルシューティング です。

コンテナーが作業を開始する前

コンテナーの準備ができていない場合、SDK は ContainerUnavailableErrorCONTAINER_UNAVAILABLE)を投げることがあります。操作はコンテナー内では実行されていません。

コールドスタート、アイドル停止のあと、またはデプロイ中によく起きます。

エラーの context には retryable: truereason(例: container_starting)、任意の retryAfterMs が含まれます。バックオフします(ある場合は retryAfterMs を使います)。その後、同じ種類の処理を再試行します。

コンテナーが作業を開始したあとに起きる失敗には、この「常に再試行する」ルールを使わないでください。

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 は、呼び出しがすでに進行中にコンテナーまたはサンドボックスが変わったことを意味します。作業は開始済みの可能性があります。

エラーの reasonretryable を使います(フィールドは Errors API を参照してください)。手順が状態を変える場合は、同じ手順を再実行する前に、サンドボックスまたは自分側の記録を確認します。

呼び出し中に SDK が接続を失った

RPCTransportError は、呼び出し中に SDK が現在のコンテナーとの接続を失ったことを意味します。後続の呼び出しは、同じコンテナーに対して成功することがあります。

これは、中断した呼び出しが何もしなかったことを 意味しません。同じ作業を繰り返す前に、チェックポイントと二重実行しても安全な手順を使うか、状態を確認してください。診断用の kind 値は Errors API にあります。

古いプロセスまたはターミナルのハンドル

プロセス ID とターミナル ID は、サンドボックス ID の 現在の コンテナーに属します。停止または置き換えのあと、古いハンドルへの呼び出しは StaleProcessHandleError または StaleTerminalHandleError を投げます。getProcessgetTerminallistProcesseslistTerminals はコンテナーを起動しません。コンテナーが動いていない場合、または現在のコンテナーに未知の ID の場合は null または [] を返します。これは例外ではありません。

リソース ID だけでなく、ジョブ(コマンド、cwdenv、チェックポイント)を保存します。古いハンドルがなくなったら、新しい exec または createTerminal を開始します。

ローカルの待機と中止

output()waitForExit()waitForLog()waitForPort()logs() のタイムアウトと AbortSignal は、その待機またはストリームだけ を終了します。プロセスは終了しません。ターミナル出力のキャンセルは PTY を終了しません。

リソースを止めたいときは process.kill()、または terminal.interrupt() / terminal.terminate() を使います。よく出るエラーは ProcessWaitTimeoutErrorProcessAbortedError です。

不正な引数

不正な cwd や環境変数、存在しない実行ファイル、同様のリクエストの問題は、値を変えるまで失敗します。同じ不正なリクエストを再試行しないでください。よく使うクラスは InvalidProcessCwdErrorInvalidProcessEnvironmentErrorProcessSpawnFailedError です。

Worker とコンテナーイメージの不一致

Worker パッケージとコンテナーイメージが一致していない、イメージが起動できない、Worker とコンテナーのあいだのセットアップが失敗した、という意味の失敗があります。

兆候 対応
RuntimeControlProtocolError(例: unsupported-protocol-version、不足または不正なメタデータ) Worker パッケージとコンテナーイメージを、同じ @cloudflare/sandbox@next 系列からデプロイします。プレビューと安定版のパッケージを混ぜないでください。
イメージが誤りまたは不足している、あるいは準備完了前にコンテナーが終了する wrangler、イメージ、またはエントリポイントを直します。同じアプリケーション呼び出しの再試行では直りません。
アカウントまたはロケーションの容量制限 同時実行を減らすか、制限を上げます。プラットフォームの制限 を参照してください。

カタログの詳細は Worker とコンテナーイメージの不一致 です。

これらは、遅い起動(ContainerUnavailableError)とは違います。両方に同じバックオフと再試行のループを使わないでください。

よくある回復手順

初回利用、またはアイドル後の復帰

エラー: ContainerUnavailableError

バックオフしたあと、作業単位全体(例: セットアップと exec)を再実行します。チェックポイントなしで途中のステップだけを実行しないでください。

Worker リクエストをまたぐ長時間ジョブ

  1. ジョブとチェックポイントを永続化します(役立つあいだはプロセス ID またはターミナル ID も)。
  2. 後続のリクエストでは、ID が残っている場合に getProcess または getTerminal を呼び出します。
  3. ハンドルが取れたら続行します(ログ、接続、待機)。
  4. null または古いハンドルのエラーになったら、チェックポイントからやり直します。
  5. ContainerUnavailableError になったら、バックオフして新しい操作で続行します。

呼び出し中のデプロイまたは置き換え

エラー: OperationInterruptedError

reasonretryable を読みます。呼び出しが何かを変えている可能性がある場合は、繰り返す前に状態を確認します。

呼び出し中の接続喪失

エラー: RPCTransportError

診断が必要なら kind を記録します。進行中の作業は実行済みの可能性があると考えます。チェックポイントまたは確認から続行し、ジョブがまだ必要なら新しい操作を開始します。

待機だけを止めた場合

エラー: ProcessWaitTimeoutErrorProcessAbortedError

観察を続ける(getProcesslogs({ since }))か、kill でプロセスを止めます。待機が終わったからといって、プロセスが終了したとは限りません。

不正な引数

エラー: InvalidProcessCwdErrorInvalidProcessEnvironmentErrorProcessSpawnFailedError、および同様のエラー

パス、環境、またはコマンドを直します(バイナリが無い場合はイメージ内のファイルも)。値を変えずに再試行しないでください。

Worker とコンテナーイメージの不一致

状況: デプロイ後、プロトコルまたはセットアップのエラーで呼び出しが失敗する、あるいはコンテナーが使える状態にならない。

エラー / 兆候: RuntimeControlProtocolError、誤ったイメージ、準備完了前のコンテナー終了

すること: Worker パッケージとコンテナーイメージを、同じ @cloudflare/sandbox@next 系列から再デプロイします。イメージ名とエントリポイントを確認します。

しないこと: 遅いコンテナー起動と同じ扱いをして、バックオフだけする。

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;
	}
}

@cloudflare/sandbox のクラスに対する instanceof を優先してください。表の全体は Errors API です。

関連情報

役に立ちましたか?