Skip to content

fix: fail benchmark reindex when indexer exits non-zero#117

Merged
SutuSebastian merged 2 commits into
mainfrom
fix/benchmark-reindex-exit-code
May 20, 2026
Merged

fix: fail benchmark reindex when indexer exits non-zero#117
SutuSebastian merged 2 commits into
mainfrom
fix/benchmark-reindex-exit-code

Conversation

@SutuSebastian
Copy link
Copy Markdown
Contributor

@SutuSebastian SutuSebastian commented May 20, 2026

Summary

benchmarkReindex recorded timings even when bun src/index.ts exited non-zero, hiding broken index runs behind plausible benchmark numbers.

Fix: check exitCode after each spawn; throw with stderr/stdout on failure. Logic extracted to benchmark-reindex.ts with injectable spawnIndexer for tests.

Test plan

  • bun test src/benchmark-reindex.test.ts — non-zero exit throws, does not add to times
  • bun run typecheck
  • CI green

Summary by CodeRabbit

  • Bug Fixes

    • Benchmark reindex now properly fails when the indexer exits with a non-zero status, preventing misleading timing results from being recorded.
  • Tests

    • Added test coverage for benchmark reindex functionality to ensure reliable error handling and accurate timing measurements.

Review Change Stack

Check child exit code and surface stderr instead of recording timings for failed indexer runs.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 20, 2026

🦋 Changeset detected

Latest commit: d378b76

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@stainless-code/codemap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@SutuSebastian has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 54 minutes and 35 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 672a8a0c-ed66-4ab6-92a0-217f3293964b

📥 Commits

Reviewing files that changed from the base of the PR and between 2265297 and d378b76.

📒 Files selected for processing (2)
  • src/benchmark-reindex.test.ts
  • src/benchmark-reindex.ts
📝 Walkthrough

Walkthrough

This PR extracts reindex benchmarking logic into a standalone, tested module with fail-fast error handling. runBenchmarkReindex runs a provided spawner for configurable iterations, measures elapsed time per run, aggregates statistics, and throws detailed errors when the spawned process exits non-zero. The logic is then integrated into benchmark.ts via a spawnIndexer adapter, replacing the previous inline implementation.

Changes

Benchmark reindex extraction and integration

Layer / File(s) Summary
Benchmark reindex module contract and implementation
src/benchmark-reindex.ts
Local timing helper, IndexerSpawnResult and IndexerSpawn types, and runBenchmarkReindex function that executes multiple runs with timing aggregation and fail-fast on non-zero exit codes.
Test coverage for benchmark reindex
src/benchmark-reindex.test.ts
Bun tests verify rejection on non-zero indexer exit and success with correct label, run count, and non-negative average timing.
Integration and refactoring in benchmark.ts
src/benchmark.ts
Import runBenchmarkReindex, introduce spawnIndexer helper to collect exit code and stdio, refactor benchmarkReindex to delegate to the new module, and remove the superseded timeMsAsync helper.
Changeset documentation
.changeset/fix-benchmark-reindex-exit-code.md
Record patch release documenting fail-fast error on non-zero indexer exit.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops with glee,
Benchmarks now extract and flee,
Timings measured, errors caught,
Spawned processes closely sought,
Tests confirm the logic's bright! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately reflects the main change: adding error handling to fail benchmark reindex when the spawned indexer exits with a non-zero status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/benchmark-reindex-exit-code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/benchmark-reindex.test.ts (1)

24-36: ⚡ Quick win

Add boundary tests for invalid runs values.

Current tests miss runs validation behavior (0, negative, non-integer), so this regression path is not locked.

🧪 Suggested tests
 describe("runBenchmarkReindex", () => {
+  it("rejects invalid runs values", async () => {
+    const spawnIndexer = async () => ({ exitCode: 0, stderr: "", stdout: "" });
+    await expect(
+      runBenchmarkReindex("bad-runs-zero", [], { runs: 0, spawnIndexer }),
+    ).rejects.toThrow(/runs >= 1/);
+    await expect(
+      runBenchmarkReindex("bad-runs-float", [], { runs: 1.5, spawnIndexer }),
+    ).rejects.toThrow(/runs >= 1/);
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/benchmark-reindex.test.ts` around lines 24 - 36, Add boundary tests for
runBenchmarkReindex to assert validation for invalid `runs` inputs (0, negative,
and non-integer). Update or add test cases in src/benchmark-reindex.test.ts that
call runBenchmarkReindex("label", [], { runs: X, spawnIndexer: ... }) with runs
set to 0, -1, and a non-integer (e.g., 1.5) and assert the function either
throws or returns a validation error; reference the runBenchmarkReindex helper
to implement these assertions and mirror existing test patterns (use async/await
and expect(...).toThrow or expect(...).toMatchObject depending on current error
behavior).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/benchmark-reindex.ts`:
- Around line 7-25: Add JSDoc for the exported API: document IndexerSpawnResult
(fields exitCode, stderr, stdout and what null exitCode means), IndexerSpawn
(contract: accepts args array, returns a Promise resolving to IndexerSpawnResult
and may reject on spawn failure), and runBenchmarkReindex (describe label, args,
opts.spawnIndexer, opts.runs default behavior, that runs is number of iterations
used to compute avg/min/max, and how failures from spawnIndexer are propagated
or handled). Place the comments immediately above the exported declarations
(IndexerSpawnResult, IndexerSpawn, and runBenchmarkReindex) and keep them
concise, specifying return shape and failure semantics.
- Around line 26-42: The code uses opts.runs directly which may be 0, negative,
or non-integer and leads to invalid stats; normalize and validate it first
(e.g., compute let runsNormalized = Number.isFinite(Number(opts.runs)) ?
Math.floor(Number(opts.runs)) : /* default */ 3, then if runsNormalized < 1 set
to 1 or throw). Replace uses of runs with runsNormalized in the loop and in the
avg calculation, ensuring timeMsAsync/spawnIndexer logic and the times array
remain unchanged; reference the variables/functions runs/opts.runs,
runsNormalized, timeMsAsync, spawnIndexer, times, avg, min, max.

---

Nitpick comments:
In `@src/benchmark-reindex.test.ts`:
- Around line 24-36: Add boundary tests for runBenchmarkReindex to assert
validation for invalid `runs` inputs (0, negative, and non-integer). Update or
add test cases in src/benchmark-reindex.test.ts that call
runBenchmarkReindex("label", [], { runs: X, spawnIndexer: ... }) with runs set
to 0, -1, and a non-integer (e.g., 1.5) and assert the function either throws or
returns a validation error; reference the runBenchmarkReindex helper to
implement these assertions and mirror existing test patterns (use async/await
and expect(...).toThrow or expect(...).toMatchObject depending on current error
behavior).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afa8f2cb-9ef2-49b0-b11b-9761a8b4e9ad

📥 Commits

Reviewing files that changed from the base of the PR and between a444c40 and 2265297.

📒 Files selected for processing (4)
  • .changeset/fix-benchmark-reindex-exit-code.md
  • src/benchmark-reindex.test.ts
  • src/benchmark-reindex.ts
  • src/benchmark.ts

Comment thread src/benchmark-reindex.ts
Comment on lines +7 to +25
export interface IndexerSpawnResult {
exitCode: number | null;
stderr: string;
stdout: string;
}

export type IndexerSpawn = (args: string[]) => Promise<IndexerSpawnResult>;

export async function runBenchmarkReindex(
label: string,
args: string[],
opts: { spawnIndexer: IndexerSpawn; runs?: number },
): Promise<{
label: string;
avg: number;
min: number;
max: number;
runs: number;
}> {
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document the exported benchmark API surface.

The exported interface/type/function are public API but currently have no accompanying docs. Add concise JSDoc that captures intent/contract (especially failure behavior and runs semantics).

📝 Proposed doc additions
 export interface IndexerSpawnResult {
   exitCode: number | null;
   stderr: string;
   stdout: string;
 }
 
+/** Spawns an indexer process for the provided CLI arguments. */
 export type IndexerSpawn = (args: string[]) => Promise<IndexerSpawnResult>;
 
+/**
+ * Benchmarks repeated reindex runs and returns aggregate timing stats.
+ * Throws when any run exits non-zero to avoid reporting failed runs as timings.
+ */
 export async function runBenchmarkReindex(

As per coding guidelines, "**/*.{ts,tsx,js,jsx}: All public APIs must have accompanying documentation".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/benchmark-reindex.ts` around lines 7 - 25, Add JSDoc for the exported
API: document IndexerSpawnResult (fields exitCode, stderr, stdout and what null
exitCode means), IndexerSpawn (contract: accepts args array, returns a Promise
resolving to IndexerSpawnResult and may reject on spawn failure), and
runBenchmarkReindex (describe label, args, opts.spawnIndexer, opts.runs default
behavior, that runs is number of iterations used to compute avg/min/max, and how
failures from spawnIndexer are propagated or handled). Place the comments
immediately above the exported declarations (IndexerSpawnResult, IndexerSpawn,
and runBenchmarkReindex) and keep them concise, specifying return shape and
failure semantics.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping JSDoc here — this is an internal benchmark helper (benchmark.ts + tests only), not package public API. Names and types are self-explanatory; we avoid signature-restating comments on small src/ utilities per project comment discipline.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SutuSebastian, understood — the export keyword here is for testability, not public package API surface, and the names+types speak for themselves. Happy to defer to the project's comment discipline. I'll note this for future reviews.

( ˘︹˘ ) 🐇


✏️ Learnings added
Learnt from: SutuSebastian
Repo: stainless-code/codemap PR: 117
File: src/benchmark-reindex.ts:7-25
Timestamp: 2026-05-20T15:16:31.042Z
Learning: In stainless-code/codemap, exported symbols in internal benchmark helpers (e.g., `IndexerSpawnResult`, `IndexerSpawn`, `runBenchmarkReindex` in `src/benchmark-reindex.ts`) do not require JSDoc. The module is consumed only by `src/benchmark.ts` and tests — `export` is used for testability, not to expose a public package API. Per project comment discipline, JSDoc is omitted when names and types are already self-explanatory, consistent with the `.agents/rules/concise-comments.md` rule.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: SutuSebastian
Repo: stainless-code/codemap PR: 75
File: src/parsed-types.ts:37-37
Timestamp: 2026-05-05T20:23:01.334Z
Learning: In the stainless-code/codemap repository, follow the codebase JSDoc conciseness rule (see `.agents/rules/concise-comments.md`): only add JSDoc to fields/functions when the behavior/meaning is not obvious from the identifier name and the TypeScript type alone. Do not require JSDoc for “self-explanatory” members where name + type are sufficient (e.g., fields like `symbols`, `imports`, `exports`, etc. in `ParsedFile`). Also, remove comments that simply restate the function/variable name; those should be deleted rather than treated as documentation.

Comment thread src/benchmark-reindex.ts
@SutuSebastian SutuSebastian merged commit 5ee5f2e into main May 20, 2026
12 checks passed
@SutuSebastian SutuSebastian deleted the fix/benchmark-reindex-exit-code branch May 20, 2026 15:21
@github-actions github-actions Bot mentioned this pull request May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant