跳转到内容
搜索文档

错误处理

最后更新 查看 MarkdownAgent 设置

Durable Object 或 Durable Objects 基础设施(如过载或网络错误)抛出的任何未捕获异常都会传播到客户端调用点。捕获这些异常允许您重试创建 DurableObjectStub 并发送请求。

属性 .retryable 设置为 True 的 JavaScript 错误建议在 Durable Object 请求是幂等的,或可以多次应用而不改变响应的情况下重试。如果请求不是幂等的,您需要决定最适合应用的方案。强烈建议在重试请求时应用指数退避。

属性 .overloaded 设置为 True 的 JavaScript 错误不应重试。如果 Durable Object 过载,重试会加剧过载并增加整体错误率。

异常如何抛出

Durable Objects 可以通过两种方式抛出异常:

  • 实现 Durable Object 类 的用户代码内可以抛出异常。此情况下,产生的异常将设置 .remote 属性为 True
  • Durable Objects 基础设施可以生成异常。基础设施异常的一些来源包括:临时内部错误、向单个 Durable Object 发送过多请求,以及由于单个 Durable Object 内缓慢或过度的 I/O(外部 API 调用或存储操作)导致排队请求过多。某些基础设施异常也可能设置 .remote 属性为 True——例如,当 Durable Object 超过其内存或 CPU 限制时。

请参阅故障排查了解 Durable Object 和/或 Durable Objects 基础设施返回的错误类型以及如何防止它们。

示例

此示例演示使用推荐的指数退避算法重试请求。

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({});
	}
}

这篇文档对您有帮助吗?