fix: resolve all 301 error handling anti-patterns across codebase

Systematic cleanup of every error handling anti-pattern detected by the
automated scanner. 289 issues fixed via code changes, 12 approved with
specific technical justifications.

Changes across 90 files:
- GENERIC_CATCH (141): Added instanceof Error type discrimination
- LARGE_TRY_BLOCK (82): Extracted helper methods to narrow try scope to ≤10 lines
- NO_LOGGING_IN_CATCH (65): Added logger/console calls for error visibility
- CATCH_AND_CONTINUE_CRITICAL_PATH (10): Added throw/return or approved overrides
- ERROR_STRING_MATCHING (2): Approved with rationale (no typed error classes)
- ERROR_MESSAGE_GUESSING (1): Replaced chained .includes() with documented pattern array
- PROMISE_CATCH_NO_LOGGING (1): Added logging to .catch() handler

Also fixes a detector bug where nested try/catch inside a catch block
corrupted brace-depth tracking, causing false positives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-19 19:57:00 -07:00
parent c9adb1c77b
commit a0dd516cd5
91 changed files with 4846 additions and 3414 deletions
+3 -1
View File
@@ -1,3 +1,4 @@
import { logger } from '../../utils/logger.js';
import type { FieldSpec, MatchRule, TranscriptSchema, WatchTarget } from './types.js';
interface ResolveContext {
@@ -142,7 +143,8 @@ export function matchesRule(
try {
const regex = new RegExp(rule.regex);
return regex.test(String(value ?? ''));
} catch {
} catch (error: unknown) {
logger.debug('WORKER', 'Invalid regex in match rule', { regex: rule.regex }, error instanceof Error ? error : undefined);
return false;
}
}
+25 -20
View File
@@ -277,7 +277,8 @@ export class TranscriptEventProcessor {
if (!(trimmed.startsWith('{') || trimmed.startsWith('['))) return value;
try {
return JSON.parse(trimmed);
} catch {
} catch (error: unknown) {
logger.debug('WORKER', 'Failed to parse JSON string', { length: trimmed.length }, error instanceof Error ? error : undefined);
return value;
}
}
@@ -321,18 +322,19 @@ export class TranscriptEventProcessor {
if (!workerReady) return;
const lastAssistantMessage = session.lastAssistantMessage ?? '';
const requestBody = JSON.stringify({
contentSessionId: session.sessionId,
last_assistant_message: lastAssistantMessage,
platformSource: session.platformSource
});
try {
await workerHttpRequest('/api/sessions/summarize', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
contentSessionId: session.sessionId,
last_assistant_message: lastAssistantMessage,
platformSource: session.platformSource
})
body: requestBody
});
} catch (error) {
} catch (error: unknown) {
logger.warn('TRANSCRIPT', 'Summary request failed', {
error: error instanceof Error ? error.message : String(error)
});
@@ -352,22 +354,25 @@ export class TranscriptEventProcessor {
const context = getProjectContext(cwd);
const projectsParam = context.allProjects.join(',');
const contextUrl = `/api/context/inject?projects=${encodeURIComponent(projectsParam)}&platformSource=${encodeURIComponent(session.platformSource)}`;
const agentsPath = expandHomePath(watch.context.path ?? `${cwd}/AGENTS.md`);
let response: Awaited<ReturnType<typeof workerHttpRequest>>;
try {
const response = await workerHttpRequest(
`/api/context/inject?projects=${encodeURIComponent(projectsParam)}&platformSource=${encodeURIComponent(session.platformSource)}`
);
if (!response.ok) return;
const content = (await response.text()).trim();
if (!content) return;
const agentsPath = expandHomePath(watch.context.path ?? `${cwd}/AGENTS.md`);
writeAgentsMd(agentsPath, content);
logger.debug('TRANSCRIPT', 'Updated AGENTS.md context', { agentsPath, watch: watch.name });
} catch (error) {
logger.warn('TRANSCRIPT', 'Failed to update AGENTS.md context', {
response = await workerHttpRequest(contextUrl);
} catch (error: unknown) {
logger.warn('TRANSCRIPT', 'Failed to fetch AGENTS.md context', {
error: error instanceof Error ? error.message : String(error)
});
return;
}
if (!response.ok) return;
const content = (await response.text()).trim();
if (!content) return;
writeAgentsMd(agentsPath, content);
logger.debug('TRANSCRIPT', 'Updated AGENTS.md context', { agentsPath, watch: watch.name });
}
}
+19 -8
View File
@@ -43,7 +43,8 @@ class FileTailer {
let size = 0;
try {
size = statSync(this.filePath).size;
} catch {
} catch (error: unknown) {
logger.debug('WORKER', 'Failed to stat transcript file', { file: this.filePath }, error instanceof Error ? error : undefined);
return;
}
@@ -152,7 +153,8 @@ export class TranscriptWatcher {
return globSync(pattern, { nodir: true, absolute: true });
}
return [inputPath];
} catch {
} catch (error: unknown) {
logger.debug('WORKER', 'Failed to stat watch path', { path: inputPath }, error instanceof Error ? error : undefined);
return [];
}
}
@@ -180,7 +182,8 @@ export class TranscriptWatcher {
if (offset === 0 && watch.startAtEnd && initialDiscovery) {
try {
offset = statSync(filePath).size;
} catch {
} catch (error: unknown) {
logger.debug('WORKER', 'Failed to stat file for startAtEnd offset', { file: filePath }, error instanceof Error ? error : undefined);
offset = 0;
}
}
@@ -216,11 +219,19 @@ export class TranscriptWatcher {
try {
const entry = JSON.parse(line);
await this.processor.processEntry(entry, watch, schema, sessionIdOverride ?? undefined);
} catch (error) {
logger.debug('TRANSCRIPT', 'Failed to parse transcript line', {
watch: watch.name,
file: basename(filePath)
}, error as Error);
} catch (error: unknown) {
if (error instanceof Error) {
logger.debug('TRANSCRIPT', 'Failed to parse transcript line', {
watch: watch.name,
file: basename(filePath)
}, error);
} else {
logger.warn('TRANSCRIPT', 'Failed to parse transcript line (non-Error thrown)', {
watch: watch.name,
file: basename(filePath),
error: String(error)
});
}
}
}