INTEGRITY Dokumentace

Zpracování chyb

Jakékoli nezachycené výjimky vyvolané Durable Object nebo vyhozené infrastrukturou Durable Objects (například kvůli přetížení nebo síťovým chybám), se předají na místo volání u klienta. Zachycením těchto výjimek můžete zopakovat pokus o vytvoření DurableObjectStub a odesílání požadavků.

Chyby JavaScriptu s vlastností .retryable nastavenou na True se doporučuje opakovat, pokud jsou požadavky na Durable Object idempotentní, tedy pokud je lze aplikovat opakovaně, aniž by se změnila odpověď. Pokud požadavky idempotentní nejsou, musíte sami zvážit, co je pro vaši aplikaci nejvhodnější. Při opakování požadavků důrazně doporučujeme použít exponenciální backoff.

Chyby JavaScriptu s vlastností .overloaded nastavenou na True by se opakovat neměly. Pokud je Durable Object přetížený, opakování přetížení ještě zhorší a zvýší celkovou chybovost.

Jak jsou výjimky vyhazovány

Durable Objects mohou vyvolat výjimku dvěma způsoby:

Viz Řešení potíží a projděte si typy chyb, které Durable Object a/nebo infrastruktura Durable Objects vrací, a jak jim předcházet.

Příklad

Tento příklad ukazuje, jak opakovat požadavky pomocí doporučeného algoritmu exponenciálního odkladu (exponential backoff).

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") || "";

		// Retry behavior can be adjusted to fit your application.
		let maxAttempts = 3;
		let baseBackoffMs = 100;
		let maxBackoffMs = 20000;

		let attempt = 0;
		while (true) {
			// Try sending the request
			try {
				// Create a Durable Object stub for each attempt, because certain types of
				// errors will break the Durable Object stub.
				const doStub = env.ErrorThrowingObject.getByName(userId);
				const resp = await doStub.fetch("http://your-do/");

				return Response.json(resp);
			} catch (e: any) {
				if (!e.retryable) {
					// Failure was not a transient internal error, so don't retry.
					break;
				}
			}
			let backoffMs = Math.min(
				maxBackoffMs,
				baseBackoffMs * Math.random() * Math.pow(2, attempt),
			);
			attempt += 1;
			if (attempt >= maxAttempts) {
				// Reached max attempts, so don't retry.
				break;
			}
			await scheduler.wait(backoffMs);
		}
		return new Response("server error", { status: 500 });
	},
} satisfies ExportedHandler<Env>;

export class ErrorThrowingObject extends DurableObject {
	constructor(state: DurableObjectState, env: Env) {
		super(state, env);

		// Any exceptions that are raised in your constructor will also set the
		// .remote property to True
		throw new Error("no good");
	}

	async fetch(req: Request) {
		// Generate an uncaught exception
		// A .remote property will be added to the exception propagated to the caller
		// and will be set to True
		throw new Error("example error");

		// We never reach this
		return Response.json({});
	}
}