From fb24bb4a1cf7bdf4b46d85e254a83c1eebba12a5 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Thu, 9 Apr 2026 04:54:31 -1000 Subject: [PATCH] refactor: selective catches in gstack-global-discover Convert 8 defensive catch blocks to selective error handling. Filesystem ops check ENOENT/EACCES, process ops check exit status. Unexpected errors now propagate instead of returning silent defaults. Co-Authored-By: Claude Opus 4.6 (1M context) --- bin/gstack-global-discover.ts | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/bin/gstack-global-discover.ts b/bin/gstack-global-discover.ts index 12797727..4e1445b3 100644 --- a/bin/gstack-global-discover.ts +++ b/bin/gstack-global-discover.ts @@ -167,8 +167,11 @@ function getGitRemote(cwd: string): string | null { stdio: ["pipe", "pipe", "pipe"], }).trim(); return remote || null; - } catch { - return null; + } catch (err: any) { + // Expected: no remote configured, repo not found, git not installed + if (err?.status !== undefined) return null; // non-zero exit from git + if (err?.code === 'ENOENT') return null; // git binary not found + throw err; } } @@ -183,8 +186,9 @@ function scanClaudeCode(since: Date): Session[] { let dirs: string[]; try { dirs = readdirSync(projectsDir); - } catch { - return []; + } catch (err: any) { + if (err?.code === 'ENOENT' || err?.code === 'EACCES') return []; + throw err; } for (const dirName of dirs) { @@ -209,8 +213,9 @@ function scanClaudeCode(since: Date): Session[] { const hasRecentFile = jsonlFiles.some((f) => { try { return statSync(join(dirPath, f)).mtime >= since; - } catch { - return false; + } catch (err: any) { + if (err?.code === 'ENOENT' || err?.code === 'EACCES') return false; + throw err; } }); if (!hasRecentFile) continue; @@ -223,8 +228,9 @@ function scanClaudeCode(since: Date): Session[] { const recentFiles = jsonlFiles.filter((f) => { try { return statSync(join(dirPath, f)).mtime >= since; - } catch { - return false; + } catch (err: any) { + if (err?.code === 'ENOENT' || err?.code === 'EACCES') return false; + throw err; } }); for (let i = 0; i < recentFiles.length; i++) { @@ -251,8 +257,9 @@ function resolveClaudeCodeCwd( .map((f) => { try { return { name: f, mtime: statSync(join(dirPath, f)).mtime.getTime() }; - } catch { - return null; + } catch (err: any) { + if (err?.code === 'ENOENT' || err?.code === 'EACCES') return null; + throw err; } }) .filter(Boolean) @@ -381,8 +388,9 @@ function scanGemini(since: Date): Session[] { let projectDirs: string[]; try { projectDirs = readdirSync(tmpDir); - } catch { - return []; + } catch (err: any) { + if (err?.code === 'ENOENT' || err?.code === 'EACCES') return []; + throw err; } for (const projectName of projectDirs) {