Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions types/defines/rpc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,57 @@ declare namespace Rpc {
>
}

/**
* Error thrown across a Workers RPC boundary — for example, from a
* `DurableObjectStub`, a service binding, a `WorkerEntrypoint`, or an
* `RpcTarget`. The Workers runtime annotates tunneled exceptions with extra
* boolean hints so client code can decide whether to retry, back off, or give
* up.
*
* All properties are optional and only present when the runtime has set them;
* they are never set to `false`.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface WorkersRpcError extends Error {
/**
* `true` when the failure is transient (for example, a lost network
* connection) and the operation is safe to retry, typically with randomized
* exponential backoff. Only retry if the request is idempotent.
*/
retryable?: boolean;

/**
* `true` when the RPC target is overloaded. Do NOT retry: additional
* requests will worsen the overload and increase the overall error rate.
*/
overloaded?: boolean;

/**
* `true` when the exception originated on the remote side, either from user
* code running inside the RPC target or from infrastructure running on its
* behalf (for example, when a Durable Object exceeds its memory or CPU
* limits).
*/
remote?: boolean;
}

/**
* Error thrown by a `DurableObjectStub` when a call to a remote Durable Object
* fails. Extends {@link WorkersRpcError} with Durable-Object-specific hints.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface DurableObjectError extends WorkersRpcError {
/**
* `true` when the Durable Object was reset (for example, due to a
* redeployment, an internal restart, or a storage operation that exceeded
* its timeout). The current stub is broken; create a new `DurableObjectStub`
* before issuing further requests.
*/
durableObjectReset?: boolean;
}

declare namespace Cloudflare {
// Type of `env`.
//
Expand Down
47 changes: 47 additions & 0 deletions types/generated-snapshot/experimental/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14196,6 +14196,53 @@ declare namespace Rpc {
Exclude<keyof T, Reserved | symbol | keyof StubBase<never>>
>;
}
/**
* Error thrown across a Workers RPC boundary — for example, from a
* `DurableObjectStub`, a service binding, a `WorkerEntrypoint`, or an
* `RpcTarget`. The Workers runtime annotates tunneled exceptions with extra
* boolean hints so client code can decide whether to retry, back off, or give
* up.
*
* All properties are optional and only present when the runtime has set them;
* they are never set to `false`.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface WorkersRpcError extends Error {
/**
* `true` when the failure is transient (for example, a lost network
* connection) and the operation is safe to retry, typically with randomized
* exponential backoff. Only retry if the request is idempotent.
*/
retryable?: boolean;
/**
* `true` when the RPC target is overloaded. Do NOT retry: additional
* requests will worsen the overload and increase the overall error rate.
*/
overloaded?: boolean;
/**
* `true` when the exception originated on the remote side, either from user
* code running inside the RPC target or from infrastructure running on its
* behalf (for example, when a Durable Object exceeds its memory or CPU
* limits).
*/
remote?: boolean;
}
/**
* Error thrown by a `DurableObjectStub` when a call to a remote Durable Object
* fails. Extends {@link WorkersRpcError} with Durable-Object-specific hints.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface DurableObjectError extends WorkersRpcError {
/**
* `true` when the Durable Object was reset (for example, due to a
* redeployment, an internal restart, or a storage operation that exceeded
* its timeout). The current stub is broken; create a new `DurableObjectStub`
* before issuing further requests.
*/
durableObjectReset?: boolean;
}
declare namespace Cloudflare {
// Type of `env`.
//
Expand Down
47 changes: 47 additions & 0 deletions types/generated-snapshot/experimental/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14167,6 +14167,53 @@ export declare namespace Rpc {
Exclude<keyof T, Reserved | symbol | keyof StubBase<never>>
>;
}
/**
* Error thrown across a Workers RPC boundary — for example, from a
* `DurableObjectStub`, a service binding, a `WorkerEntrypoint`, or an
* `RpcTarget`. The Workers runtime annotates tunneled exceptions with extra
* boolean hints so client code can decide whether to retry, back off, or give
* up.
*
* All properties are optional and only present when the runtime has set them;
* they are never set to `false`.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
export interface WorkersRpcError extends Error {
/**
* `true` when the failure is transient (for example, a lost network
* connection) and the operation is safe to retry, typically with randomized
* exponential backoff. Only retry if the request is idempotent.
*/
retryable?: boolean;
/**
* `true` when the RPC target is overloaded. Do NOT retry: additional
* requests will worsen the overload and increase the overall error rate.
*/
overloaded?: boolean;
/**
* `true` when the exception originated on the remote side, either from user
* code running inside the RPC target or from infrastructure running on its
* behalf (for example, when a Durable Object exceeds its memory or CPU
* limits).
*/
remote?: boolean;
}
/**
* Error thrown by a `DurableObjectStub` when a call to a remote Durable Object
* fails. Extends {@link WorkersRpcError} with Durable-Object-specific hints.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
export interface DurableObjectError extends WorkersRpcError {
/**
* `true` when the Durable Object was reset (for example, due to a
* redeployment, an internal restart, or a storage operation that exceeded
* its timeout). The current stub is broken; create a new `DurableObjectStub`
* before issuing further requests.
*/
durableObjectReset?: boolean;
}
export declare namespace Cloudflare {
// Type of `env`.
//
Expand Down
47 changes: 47 additions & 0 deletions types/generated-snapshot/latest/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13536,6 +13536,53 @@ declare namespace Rpc {
Exclude<keyof T, Reserved | symbol | keyof StubBase<never>>
>;
}
/**
* Error thrown across a Workers RPC boundary — for example, from a
* `DurableObjectStub`, a service binding, a `WorkerEntrypoint`, or an
* `RpcTarget`. The Workers runtime annotates tunneled exceptions with extra
* boolean hints so client code can decide whether to retry, back off, or give
* up.
*
* All properties are optional and only present when the runtime has set them;
* they are never set to `false`.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface WorkersRpcError extends Error {
/**
* `true` when the failure is transient (for example, a lost network
* connection) and the operation is safe to retry, typically with randomized
* exponential backoff. Only retry if the request is idempotent.
*/
retryable?: boolean;
/**
* `true` when the RPC target is overloaded. Do NOT retry: additional
* requests will worsen the overload and increase the overall error rate.
*/
overloaded?: boolean;
/**
* `true` when the exception originated on the remote side, either from user
* code running inside the RPC target or from infrastructure running on its
* behalf (for example, when a Durable Object exceeds its memory or CPU
* limits).
*/
remote?: boolean;
}
/**
* Error thrown by a `DurableObjectStub` when a call to a remote Durable Object
* fails. Extends {@link WorkersRpcError} with Durable-Object-specific hints.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
interface DurableObjectError extends WorkersRpcError {
/**
* `true` when the Durable Object was reset (for example, due to a
* redeployment, an internal restart, or a storage operation that exceeded
* its timeout). The current stub is broken; create a new `DurableObjectStub`
* before issuing further requests.
*/
durableObjectReset?: boolean;
}
declare namespace Cloudflare {
// Type of `env`.
//
Expand Down
47 changes: 47 additions & 0 deletions types/generated-snapshot/latest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13507,6 +13507,53 @@ export declare namespace Rpc {
Exclude<keyof T, Reserved | symbol | keyof StubBase<never>>
>;
}
/**
* Error thrown across a Workers RPC boundary — for example, from a
* `DurableObjectStub`, a service binding, a `WorkerEntrypoint`, or an
* `RpcTarget`. The Workers runtime annotates tunneled exceptions with extra
* boolean hints so client code can decide whether to retry, back off, or give
* up.
*
* All properties are optional and only present when the runtime has set them;
* they are never set to `false`.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
export interface WorkersRpcError extends Error {
/**
* `true` when the failure is transient (for example, a lost network
* connection) and the operation is safe to retry, typically with randomized
* exponential backoff. Only retry if the request is idempotent.
*/
retryable?: boolean;
/**
* `true` when the RPC target is overloaded. Do NOT retry: additional
* requests will worsen the overload and increase the overall error rate.
*/
overloaded?: boolean;
/**
* `true` when the exception originated on the remote side, either from user
* code running inside the RPC target or from infrastructure running on its
* behalf (for example, when a Durable Object exceeds its memory or CPU
* limits).
*/
remote?: boolean;
}
/**
* Error thrown by a `DurableObjectStub` when a call to a remote Durable Object
* fails. Extends {@link WorkersRpcError} with Durable-Object-specific hints.
*
* @see https://developers.cloudflare.com/durable-objects/best-practices/error-handling/
*/
export interface DurableObjectError extends WorkersRpcError {
/**
* `true` when the Durable Object was reset (for example, due to a
* redeployment, an internal restart, or a storage operation that exceeded
* its timeout). The current stub is broken; create a new `DurableObjectStub`
* before issuing further requests.
*/
durableObjectReset?: boolean;
}
export declare namespace Cloudflare {
// Type of `env`.
//
Expand Down
38 changes: 38 additions & 0 deletions types/test/types/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,44 @@ export default <ExportedHandler<Env>>{
>;
}

// Verify the shape of WorkersRpcError and DurableObjectError matches what
// the runtime stamps onto tunneled exceptions from RPC / DO stubs.
{
try {
const stub = env.RPC_OBJECT.get(env.RPC_OBJECT.newUniqueId());
await stub.fetch('https://example.com');
} catch (e) {
// Base RPC error: retryable / overloaded / remote apply to any
// tunneled Workers RPC exception (Fetcher, service binding,
// WorkerEntrypoint, RpcTarget, Durable Object, Workflow).
const rpcErr = e as WorkersRpcError;
expectTypeOf(rpcErr).toExtend<Error>();
expectTypeOf(rpcErr.retryable).toEqualTypeOf<boolean | undefined>();
expectTypeOf(rpcErr.overloaded).toEqualTypeOf<boolean | undefined>();
expectTypeOf(rpcErr.remote).toEqualTypeOf<boolean | undefined>();

// `durableObjectReset` is DO-specific and not on the base RPC error.
expectTypeOf<WorkersRpcError>().not.toHaveProperty(
'durableObjectReset'
);

// Durable-Object-specific error adds `durableObjectReset`.
const doErr = e as DurableObjectError;
expectTypeOf(doErr).toExtend<WorkersRpcError>();
expectTypeOf(doErr).toExtend<Error>();
expectTypeOf(doErr.retryable).toEqualTypeOf<boolean | undefined>();
expectTypeOf(doErr.overloaded).toEqualTypeOf<boolean | undefined>();
expectTypeOf(doErr.remote).toEqualTypeOf<boolean | undefined>();
expectTypeOf(doErr.durableObjectReset).toEqualTypeOf<
boolean | undefined
>();

// Both are assignable to Error (they extend it).
const asError: Error = doErr;
expectTypeOf(asError).toExtend<Error>();
}
}

return new Response();
},
};
Loading