retryHandler
Problem
LLM API calls fail. Networks time out. Rate limits hit. A single failure should not kill your agent run — but writing manual retry logic with exponential backoff in every async function is tedious and easy to get wrong.
Solution
retryHandler wraps any async function and retries it automatically on failure. It uses exponential backoff — each retry waits longer than the last — and throws only after all retries are exhausted. One wrapper, any async function.
Feature & Use-Case
Use retryHandler when:
- Your LLM provider calls occasionally fail with network or rate-limit errors
- You are calling external APIs inside tools that are unreliable
- You want automatic recovery without try-catch blocks in every function
- You are building a production Node.js agent where reliability matters
Import
import { retryHandler } from "llm-layer-engine";Function Signature
async function retryHandler<T>(
fn: () => Promise<T>,
options?: RetryOptions
): Promise<T>RetryOptions
type RetryOptions = {
retries?: number; // Max attempts. Default: 3
delay?: number; // Initial delay in ms. Default: 500
factor?: number; // Backoff multiplier. Default: 2
};Backoff Calculation
| Attempt | Delay |
|---|---|
| 1st retry | 500ms |
| 2nd retry | 1000ms (500 × 2) |
| 3rd retry | 2000ms (1000 × 2) |
| After 3rd | Throws error |
Example — Wrap a Provider Call
import { retryHandler } from "llm-layer-engine";
const result = await retryHandler(
() => myProvider.run({ messages, config }),
{ retries: 3, delay: 500, factor: 2 }
);
console.log(result.content);If the provider fails on attempt 1, retryHandler waits 500ms and tries again. Fails again — waits 1000ms. Fails again — throws.
Example — Wrap a Tool’s External API Call
import { retryHandler, registerTool } from "llm-layer-engine";
import axios from "axios";
registerTool({
name: "get_stock_price",
execute: async ({ ticker }) => {
return await retryHandler(
() => axios.get(`https://api.stocks.com/price/${ticker}`).then((r) => r.data),
{ retries: 4, delay: 300, factor: 1.5 }
);
},
});The tool retries the HTTP call up to 4 times with 1.5× backoff before failing.
Example — Custom Retry Count for Fast Failures
// For a fast-failing health check — 2 retries, 200ms delay
const health = await retryHandler(
() => checkServiceHealth(),
{ retries: 2, delay: 200, factor: 1 }
);Setting factor: 1 disables exponential growth — the delay stays constant.
Error After All Retries
try {
await retryHandler(() => alwaysFailingFn(), { retries: 2, delay: 100 });
} catch (err) {
console.error(err.message);
// → "Maximum retries (2) exceeded"
}Conclusion
retryHandler is a single-function solution to unreliable async calls. Wrap your provider run, your tool API calls, or any async operation that might flake. Configure retries and delay per call — heavier for LLM calls, lighter for internal pings. Do not put retry logic inside tools manually — use this instead.