コンテンツにスキップ

エラーハンドリング

自分のDurable Objectコードによって生成されたエラー(例外)や、Durable Objectsのインフラストラクチャによってスローされた例外(過負荷やネットワークエラーなど)を処理する方法を確認します。

例外がスローされる方法

Durable Objectsは、次の2つの方法のいずれかで例外をスローできます。

  • Durable Objectクラスを実装するユーザーコード内で例外がスローされることがあります。この場合、結果の例外には.remoteプロパティがTrueに設定されます。
  • Durable Objectのインフラストラクチャによって例外が生成されることがあります。インフラストラクチャ例外のいくつかの発生源には、一時的な内部エラー、単一のDurable Objectに対して過剰なリクエストを送信すること、個々のDurable Object内での遅いまたは過剰なI/O(外部API呼び出しやストレージ操作)によってリクエストがキューに溜まりすぎることが含まれます。一部のインフラストラクチャ例外にも.remoteプロパティがTrueに設定されることがあります。たとえば、Durable ObjectがメモリまたはCPUの制限を超えた場合です。

トラブルシューティングを参照して、Durable Objectおよび/またはDurable Objectsインフラストラクチャによって返されるエラーの種類と、それを防ぐ方法を確認してください。

スタブの理解

Durable Objectスタブは、リモートDurable Objectにリクエストを送信するために使用されるクライアントオブジェクトです。Durable Objectにリクエストを送信する方法については、Durable Objectスタブの作成およびワーカーからDurable Objectsにアクセスするを参照してください。

Durable Objectまたはそのインフラストラクチャによってスローされた未捕捉の例外は、クライアントの呼び出し元に伝播されます。これらの例外をキャッチすることで、Durable Objectスタブの作成とリクエストの送信を再試行できます。

import { DurableObject } from "cloudflare:workers";
export interface Env {
ErrorThrowingObject: DurableObjectNamespace;
}
export default {
async fetch(request, env, ctx) {
let userId = new URL(request.url).searchParams.get("userId") || "";
const id = env.ErrorThrowingObject.idFromName(userId);
// 再試行の動作はアプリケーションに合わせて調整できます。
let maxAttempts = 3;
let baseBackoffMs = 100;
let maxBackoffMs = 20000;
let attempt = 0;
while (true) {
// リクエストを送信しようとする
try {
// 特定のタイプのエラーがDurable Objectスタブを壊すため、
// 各試行のためにDurable Objectスタブを作成します。
const doStub = env.ErrorThrowingObject.get(id);
const resp = await doStub.fetch("http://your-do/");
return Response.json(resp);
} catch (e: any) {
if (!e.retryable) {
// 失敗は一時的な内部エラーではなかったので、再試行しません。
break;
}
}
let backoffMs = Math.min(maxBackoffMs, baseBackoffMs * Math.random() * Math.pow(2, attempt));
attempt += 1;
if (attempt >= maxAttempts) {
// 最大試行回数に達したので、再試行しません。
break;
}
await scheduler.wait(backoffMs);
}
return new Response("サーバーエラー", { status: 500 });
},
} satisfies ExportedHandler<Env>;
export class ErrorThrowingObject extends DurableObject {
constructor(state: DurableObjectState, env: Env) {
super(state, env);
// コンストラクタ内で発生した例外は、.remoteプロパティをTrueに設定します
throw new Error("良くない");
}
async fetch(req: Request) {
// 未捕捉の例外を生成します
// 呼び出し元に伝播される例外に.remoteプロパティが追加され、
// Trueに設定されます
throw new Error("例外エラー");
// ここには到達しません
return Response.json({});
}
};