Cloudflare Workersの開発環境で Service Bindingが動かない時の対処法
Cloudflare Workers で Service Binding を使用して Worker 間通信を実装していると、開発環境で予期せぬ 503 エラーに遭遇することがあります。本番環境では正常に動作するのに、開発 […]
目次
Cloudflare Workers で Service Binding を使用して Worker 間通信を実装していると、開発環境で予期せぬ 503 エラーに遭遇することがあります。本番環境では正常に動作するのに、開発サーバーでは “Couldn’t find a local dev session” というエラーメッセージとともに通信が失敗しました。OG 画像生成 API の実装を通じて遭遇したこの問題について、原因と環境差異を吸収するフォールバック実装パターンを紹介します。
発生した問題
開発環境で Worker に Service Binding 経由のリクエストを実行すると、次のエラーが発生していました。
ステータスコード: 503 Service Unavailable
レスポンスボディ: Couldn't find a local dev session for the "default" entrypoint of service "cf-ogp-image-gen-worker" to proxy to
本番環境(Cloudflare Workers にデプロイ後)では同じコードが正常に動作します。開発環境でのみ Service Binding が失敗するという、環境差異による問題が発生していました。Service Binding を使用して Worker 間通信を行うすべてのエンドポイントが影響を受けます。
Service Bindingはローカル環境で動作しない
この問題の根本原因は、開発環境における Service Binding の動作仕様にあります。
Cloudflare Workers の Service Binding は本番環境では自動的に Worker 間の接続を確立します。しかし開発環境では、Cloudflare Workers の実行環境が完全にはエミュレートされません。そのため Service Binding が接続先 Worker のローカルセッションを見つけられず、503 エラーを返します。
フォールバック実装
この問題を解決するため、Service Binding が失敗した場合に通常の HTTP fetch へフォールバックする処理を実装しました。以下がその実装コードです。
let response: Response
if (ogImageGenerator) {
response = await ogImageGenerator.fetch(ogImageUrl, { headers })
// Service Binding が 503 エラーを返し、ローカル開発セッションが見つからない場合は通常の fetch にフォールバック
if (!response.ok && response.status === 503) {
const responseBodyText = await response.clone().text().catch(() => '')
if (responseBodyText.includes("Couldn't find a local dev session")) {
response = await fetch(ogImageUrl, { headers })
}
}
} else {
response = await fetch(ogImageUrl, { headers })
}
まず Service Binding 経由で fetch を試行します。レスポンスが 503 エラーであり、かつレスポンスボディに “Couldn’t find a local dev session” が含まれる場合のみ、通常の HTTP fetch にフォールバックします。
レスポンスボディの確認
フォールバック判定にレスポンスボディを使用している理由は、503 エラーの原因を特定するためです。
Worker の過負荷など、他の理由で 503 が返される可能性もあります。そのような場合はフォールバックせず、エラーをそのまま返すべきといえます。レスポンスボディの読み取りには response.clone() を使用しています。レスポンスストリームを複数回読み取るために必要な処理です。clone() せずに text() を呼び出すと、後続の処理でレスポンスボディを利用できなくなってしまいます。
const responseBodyText = await response.clone().text().catch(() => '')
.catch(() => '') により、万が一レスポンスボディの読み取りに失敗しても、空文字列を返して処理を継続できるようにしています。
動作確認と今後の展開
実装後、開発環境でエンドポイントにアクセスし、正常に 200 OK が返ることを確認しました。
Service Binding が 503 を返した際に自動的に HTTP fetch へフォールバックされる動作も検証済みです。本番環境では引き続き Service Binding を使用するため、既存の動作に変更はありません。この実装パターンは、他のサムネイル生成エンドポイントにも適用できます。同様に Service Binding を使用している他の Worker 間通信でも、開発環境での問題に遭遇している場合は有効な解決策となるはずです。
今後の改善として、フォールバック処理のログ出力を開発環境に限定して追加することで、問題の発生を開発者が認識しやすくなります。また、統合テストに開発環境でのフォールバック動作を含めることで、リグレッションを防げるかもしれません。
まとめ
Cloudflare Workers の Service Binding は強力な Worker 間通信の仕組みですが、開発環境では制約があります。
“Couldn’t find a local dev session” エラーに遭遇した場合、Service Binding の失敗を検出して HTTP fetch へフォールバックする実装により、開発環境と本番環境の両方で正常に動作するコードを書けます。フォールバック条件を厳密に設定することで、本番環境のパフォーマンスやセキュリティを損なうことなく、開発体験を改善できるでしょう。同様の問題に直面している開発者の参考になれば幸いです。