Skip to content

Commit 00e409e

Browse files
committed
fix retry attempt validation
1 parent dfcb8c1 commit 00e409e

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

src/tools.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ export function sleep(ms) {
122122
* Retry a function with exponential backoff
123123
*/
124124
export async function retry(fn, maxAttempts = 3, baseDelay = 1000) {
125+
if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
126+
throw new Error('retry maxAttempts must be a positive integer');
127+
}
125128
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
126129
try {
127130
return await fn();

test/tools.test.mjs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { fileURLToPath } from "node:url";
1515
import { spawn } from "node:child_process";
1616
import test from "node:test";
1717

18-
import { TOOLS, resolveTool, toolList } from "../src/tools.mjs";
18+
import { TOOLS, resolveTool, retry, toolList } from "../src/tools.mjs";
1919

2020
const BIN = fileURLToPath(new URL("../bin/moshcode.mjs", import.meta.url));
2121

@@ -204,3 +204,25 @@ test("moshcode install reports an Object.prototype name as unknown", async () =>
204204
assert.match(result.stderr, /usage: moshcode install <engine\|tool>/);
205205
assert.doesNotMatch(result.stderr, /TypeError/);
206206
});
207+
208+
test("retry rejects non-positive attempt limits", async () => {
209+
let calls = 0;
210+
211+
await assert.rejects(
212+
retry(() => { calls++; }, 0, 1),
213+
/maxAttempts must be a positive integer/,
214+
);
215+
assert.equal(calls, 0);
216+
});
217+
218+
test("retry retries until a later attempt succeeds", async () => {
219+
let calls = 0;
220+
const result = await retry(() => {
221+
calls++;
222+
if (calls < 2) throw new Error("not yet");
223+
return "ok";
224+
}, 2, 1);
225+
226+
assert.equal(result, "ok");
227+
assert.equal(calls, 2);
228+
});

0 commit comments

Comments
 (0)