Retry Plugin
Retry Plugin automatically retries failed requests based on customizable retry strategies, improving the resilience of your application.
Setup
import { RetryLinkPlugin, RetryLinkPluginContext } from '@orpc/client/plugins'
interface ClientContext extends RetryLinkPluginContext {}
const link = new RPCLink<ClientContext>({
plugins: [
new RetryLinkPlugin(),
],
})
Usage
By default, retries are disabled. To enable retries, set the retry count in the request context:
const const planets: {
id: number;
name: string;
description?: string | undefined;
}[]
planets = await const client: {
planet: {
list: ProcedureClient<RetryLinkPluginContext, ZodObject<{
limit: ZodOptional<ZodNumber>;
cursor: ZodDefault<ZodNumber>;
}, $strip>, ZodArray<ZodObject<{
id: ZodNumber;
name: ZodString;
description: ZodOptional<ZodString>;
}, $strip>>, object, never>;
find: ProcedureClient<RetryLinkPluginContext, ZodObject<{
id: ZodNumber;
}, $strip>, ZodObject<...>, object, never>;
create: ProcedureClient<...>;
};
}
client.planet: {
list: ProcedureClient<RetryLinkPluginContext, ZodObject<{
limit: ZodOptional<ZodNumber>;
cursor: ZodDefault<ZodNumber>;
}, $strip>, ZodArray<ZodObject<{
id: ZodNumber;
name: ZodString;
description: ZodOptional<ZodString>;
}, $strip>>, object, never>;
find: ProcedureClient<RetryLinkPluginContext, ZodObject<{
id: ZodNumber;
}, $strip>, ZodObject<...>, object, never>;
create: ProcedureClient<...>;
}
planet.list: Client
(input: {
limit?: number | undefined;
cursor?: number | undefined;
}, options?: FriendlyClientOptions<RetryLinkPluginContext> | undefined) => PromiseWithError<{
id: number;
name: string;
description?: string | undefined;
}[], Error>
list({ limit?: number | undefinedlimit: 10 }, {
context?: RetryLinkPluginContext | undefinedcontext: {
RetryLinkPluginContext.retry?: Value<Promisable<number>, [Omit<StandardLinkInterceptorOptions<RetryLinkPluginContext>, "next">]> | undefinedMaximum retry attempts before throwing.
Use `Number.POSITIVE_INFINITY` for infinite retries (e.g. for AsyncIteratorObject).retry: 3, // Maximum retry attempts
RetryLinkPluginContext.retryDelay?: Value<Promisable<number>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]> | undefinedDelay (in ms) before retrying.retryDelay: 2000, // Delay between retries in ms
RetryLinkPluginContext.shouldRetry?: Value<Promisable<boolean>, [RetryLinkPluginAttemptOptions<RetryLinkPluginContext>]> | undefinedDetermine whether to retry.shouldRetry: options: RetryLinkPluginAttemptOptions<RetryLinkPluginContext>options => true, // Determines whether to retry based on the error
RetryLinkPluginContext.onRetry?: ((options: RetryLinkPluginAttemptOptions<RetryLinkPluginContext>) => void | ((isSuccess: boolean) => void)) | undefinedHook called before each retry. Can return a cleanup callback.onRetry: (options: RetryLinkPluginAttemptOptions<RetryLinkPluginContext>options) => {
// Hook executed on each retry
return (isSuccess: booleanisSuccess) => {
// Execute after the retry is complete
}
},
}
})
Event Source Simulation
To replicate the behavior of EventSource for an AsyncIteratorObject, use the following configuration:
const streaming = await client.streaming('the input', {
context: {
retry: Number.POSITIVE_INFINITY,
}
})
for await (const message of streaming) {
console.log(message)
}
Learn More
For implementation details, see the source code.