@autobe/agent
Version:
AI backend server code generator
92 lines • 4.02 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.randomBackoffRetry = randomBackoffRetry;
exports.randomBackoffStrategy = randomBackoffStrategy;
/**
* @param fn Function to Apply the retry logic.
* @param maxRetries How many time to try. Max Retry is 5.
* @returns
*/
function randomBackoffRetry(fn_1) {
return __awaiter(this, arguments, void 0, function* (fn, options = {}) {
const { maxRetries = 5, baseDelay = 4000, maxDelay = 60000, jitter = 0.8, handleError = isRetryError, } = options;
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return yield fn();
}
catch (err) {
lastError = err;
if (attempt === maxRetries - 1)
throw err;
if (!handleError(err))
throw err;
const tempDelay = Math.min(baseDelay * 2 ** attempt, maxDelay);
const delay = tempDelay * (1 + Math.random() * jitter);
yield new Promise((res) => setTimeout(res, delay));
}
}
throw lastError;
});
}
function randomBackoffStrategy(props) {
const { count, error } = props;
if (count > 5) {
throw error;
}
if (isRetryError(error) === false) {
throw error;
}
const baseDelay = 4000;
const maxDelay = 60000;
const jitter = 0.8;
const tempDelay = Math.min(baseDelay * 2 ** count, maxDelay);
const delay = tempDelay * (1 + Math.random() * jitter);
return delay;
}
function isRetryError(error) {
var _a, _b, _c, _d;
// 1) Quota exceeded → No retry
if ((error === null || error === void 0 ? void 0 : error.code) === "insufficient_quota" ||
((_a = error === null || error === void 0 ? void 0 : error.error) === null || _a === void 0 ? void 0 : _a.type) === "insufficient_quota") {
return false;
}
// 2) 5xx / server_error → Retry
if ((typeof (error === null || error === void 0 ? void 0 : error.status) === "number" && error.status >= 500) ||
((_b = error === null || error === void 0 ? void 0 : error.error) === null || _b === void 0 ? void 0 : _b.type) === "server_error") {
return true;
}
// 3) HTTP 429
if ((error === null || error === void 0 ? void 0 : error.status) === 429) {
return true;
}
// 4) undici / network related
const code = (error === null || error === void 0 ? void 0 : error.code) || ((_c = error === null || error === void 0 ? void 0 : error.cause) === null || _c === void 0 ? void 0 : _c.code);
if ([
"UND_ERR_SOCKET",
"UND_ERR_CONNECT_TIMEOUT",
"ETIMEDOUT",
"ECONNRESET",
"EPIPE",
].includes(code)) {
return true;
}
// 5) fetch abort
if ((error === null || error === void 0 ? void 0 : error.message) === "terminated" || (error === null || error === void 0 ? void 0 : error.name) === "AbortError") {
return true;
}
if ((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.startsWith(`SyntaxError: Expected ',' or '}' after property value in JSON at position`)) {
return true;
}
return false;
}
//# sourceMappingURL=backoffRetry.js.map