Skip to content

Commit 4db0888

Browse files
oratisclaude
andcommitted
fix: satisfy the two rules @eslint/js 10 turns on
The bump was red because eslint 10's recommended set adds `preserve-caught-error` and `no-useless-assignment`, and nine existing sites break them. Both findings are real, so they are fixed rather than silenced. preserve-caught-error (5) — settings loading (twice), the directory trust store, the hook trust file, and the MCP `headersHelper` each wrapped a caught error in a new Error carrying only `.message`. A JSON parse failure or a spawn error therefore arrived with its stack, `errno` and `path` gone: the message says "Failed to parse ~/.deepcode/ settings.json: Unexpected token" and nothing says which byte, or that the real failure was EACCES. Each now passes `{ cause }`. no-useless-assignment (4) — `patch`/`binary` in workspace-diff and `stdout` in the Grep tool were initialised and then overwritten on every path that reads them; the initialisers only suppressed TypeScript's definite-assignment analysis. Dropping them lets tsc prove what the initialiser was papering over, and it does. In `parseQName` the `pos++` before `break` consumed the DNS root label for a variable nothing reads after the loop. Note eslint itself was already 10.8.0 in the lockfile — only `@eslint/js` was pinned at 9, so the repo was running a v10 engine against a v9 recommended config. This closes that gap. typecheck, lint, format, docs clean; 1671 tests pass, 19 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 52c3d79 commit 4db0888

8 files changed

Lines changed: 24 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
181181

182182
### 🐛 Fixed
183183

184+
- **A rethrown error keeps the one that caused it.** Five places wrapped a
185+
caught error in a new `Error` carrying only its `.message` — settings and
186+
trust-store loading, the hook trust file, and the MCP `headersHelper` — so a
187+
parse failure or a spawn error arrived with the original stack, `errno` and
188+
`path` discarded. They now pass `{ cause }`, and ESLint's `preserve-caught-error`
189+
keeps the next one from being written.
190+
184191
- **Tool output could flood the model's context, or vanish** (#268). Two defects,
185192
one cause: nothing central bounded what a tool result put in front of the
186193
model, so each tool improvised.

apps/server/src/workspace-diff.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ export async function collectWorkspaceDiff(cwd: string): Promise<WorkspaceDiffRe
3535
const files: WorkspaceDiffFile[] = [];
3636

3737
for (const entry of selected) {
38-
let patch = '';
39-
let binary = false;
38+
let patch: string;
39+
let binary: boolean;
4040
let fileTruncated = false;
4141
if (entry.untracked || !hasHead) {
4242
const captured = await addedFilePatch(workspace, entry.path, remainingBytes);

packages/core/src/config/hook-trust.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ export class HookTrustStore {
3838
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
3939
return { version: 1, directories: {} };
4040
}
41-
throw new Error(`Failed to load hook trust: ${(error as Error).message}`);
41+
throw new Error(`Failed to load hook trust: ${(error as Error).message}`, {
42+
cause: error,
43+
});
4244
}
4345
}
4446

packages/core/src/config/loader.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ async function readJson(path: string): Promise<DeepCodeSettings | undefined> {
9393
} catch (err) {
9494
const code = (err as NodeJS.ErrnoException).code;
9595
if (code === 'ENOENT') return undefined;
96-
throw new Error(`Failed to parse ${path}: ${(err as Error).message}`);
96+
throw new Error(`Failed to parse ${path}: ${(err as Error).message}`, { cause: err });
9797
}
9898
}
9999

@@ -104,7 +104,9 @@ async function readJsonRequired(path: string): Promise<DeepCodeSettings> {
104104
const raw = await fs.readFile(path, 'utf8');
105105
return parseSettings(raw, path);
106106
} catch (err) {
107-
throw new Error(`--settings: cannot load ${path}: ${(err as Error).message}`);
107+
throw new Error(`--settings: cannot load ${path}: ${(err as Error).message}`, {
108+
cause: err,
109+
});
108110
}
109111
}
110112

packages/core/src/config/trust-store.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ export class DirectoryTrustStore {
3333
return validateState(parsed);
3434
} catch (error) {
3535
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { dirs: {} };
36-
throw new Error(`Failed to load directory trust: ${(error as Error).message}`);
36+
throw new Error(`Failed to load directory trust: ${(error as Error).message}`, {
37+
cause: error,
38+
});
3739
}
3840
}
3941

packages/core/src/mcp/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ async function resolveAuthHeaders(config: McpServerConfig): Promise<Record<strin
153153
});
154154
Object.assign(headers, parseHelperOutput(stdout));
155155
} catch (err) {
156-
throw new Error(`headersHelper failed: ${(err as Error).message}`);
156+
throw new Error(`headersHelper failed: ${(err as Error).message}`, { cause: err });
157157
}
158158
}
159159
return headers;

packages/core/src/sandbox/dns-proxy.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,9 @@ export function parseQName(buf: Buffer): string | null {
9191
while (pos < buf.length) {
9292
const len = buf[pos];
9393
if (len === undefined) return null;
94-
if (len === 0) {
95-
pos++;
96-
break;
97-
}
94+
// The root label ends the name. `pos` is not read after the loop, so
95+
// there is nothing left to consume it for.
96+
if (len === 0) break;
9897
if (len > 63) return null; // compression / invalid
9998
pos++;
10099
if (pos + len > buf.length) return null;

packages/core/src/tools/grep.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export const GrepTool: ToolHandler = {
145145

146146
args.push('--', input.pattern, searchPath);
147147

148-
let stdout = '';
148+
let stdout: string;
149149
try {
150150
const result = await execFileAsync('rg', args, {
151151
cwd: ctx.cwd,

0 commit comments

Comments
 (0)