fix: enhance test stability and error handling for worktree operations

- Updated feature lifecycle tests to ensure the correct modal close button is selected, improving test reliability.
- Refactored worktree integration tests for better readability and maintainability by formatting function calls and assertions.
- Introduced error handling improvements in the server routes to suppress unnecessary ENOENT logs for optional files, reducing noise in test outputs.
- Enhanced logging for worktree errors to conditionally suppress expected errors in test environments, improving clarity in error reporting.
This commit is contained in:
Cody Seibert
2025-12-16 18:44:52 -05:00
parent ebc99d06eb
commit 360b7ebe08
6 changed files with 320 additions and 80 deletions

View File

@@ -7,6 +7,23 @@ import fs from "fs/promises";
import { validatePath } from "../../../lib/security.js";
import { getErrorMessage, logError } from "../common.js";
// Optional files that are expected to not exist in new projects
// Don't log ENOENT errors for these to reduce noise
const OPTIONAL_FILES = ["categories.json"];
function isOptionalFile(filePath: string): boolean {
return OPTIONAL_FILES.some((optionalFile) => filePath.endsWith(optionalFile));
}
function isENOENT(error: unknown): boolean {
return (
error !== null &&
typeof error === "object" &&
"code" in error &&
error.code === "ENOENT"
);
}
export function createReadHandler() {
return async (req: Request, res: Response): Promise<void> => {
try {
@@ -22,7 +39,11 @@ export function createReadHandler() {
res.json({ success: true, content });
} catch (error) {
logError(error, "Read file failed");
// Don't log ENOENT errors for optional files (expected to be missing in new projects)
const shouldLog = !(isENOENT(error) && isOptionalFile(req.body?.filePath || ""));
if (shouldLog) {
logError(error, "Read file failed");
}
res.status(500).json({ success: false, error: getErrorMessage(error) });
}
};

View File

@@ -34,6 +34,42 @@ export async function isGitRepo(repoPath: string): Promise<boolean> {
}
}
/**
* Check if an error is ENOENT (file/path not found or spawn failed)
* These are expected in test environments with mock paths
*/
export function isENOENT(error: unknown): boolean {
return (
error !== null &&
typeof error === "object" &&
"code" in error &&
error.code === "ENOENT"
);
}
/**
* Check if a path is a mock/test path that doesn't exist
*/
export function isMockPath(worktreePath: string): boolean {
return worktreePath.startsWith("/mock/") || worktreePath.includes("/mock/");
}
/**
* Conditionally log worktree errors - suppress ENOENT for mock paths
* to reduce noise in test output
*/
export function logWorktreeError(
error: unknown,
message: string,
worktreePath?: string
): void {
// Don't log ENOENT errors for mock paths (expected in tests)
if (isENOENT(error) && worktreePath && isMockPath(worktreePath)) {
return;
}
logError(error, message);
}
// Re-export shared utilities
export { getErrorMessageShared as getErrorMessage };
export const logError = createLogError(logger);

View File

@@ -5,7 +5,7 @@
import type { Request, Response } from "express";
import { exec } from "child_process";
import { promisify } from "util";
import { getErrorMessage, logError } from "../common.js";
import { getErrorMessage, logWorktreeError } from "../common.js";
const execAsync = promisify(exec);
@@ -86,7 +86,8 @@ export function createListBranchesHandler() {
},
});
} catch (error) {
logError(error, "List branches failed");
const worktreePath = req.body?.worktreePath;
logWorktreeError(error, "List branches failed", worktreePath);
res.status(500).json({ success: false, error: getErrorMessage(error) });
}
};