feat: improve error handling in terminal settings retrieval and enhance path normalization

- Wrapped the terminal settings retrieval in a try-catch block to handle potential errors and respond with a 500 status and error details.
- Updated path normalization logic to skip resolution for WSL UNC paths, preventing potential issues with path handling in Windows Subsystem for Linux.
- Enhanced unit tests for session termination to include timer-based assertions for graceful session killing.
This commit is contained in:
SuperComboGamer
2025-12-20 23:35:03 -05:00
parent 820f43078b
commit f504a00ce6
3 changed files with 30 additions and 11 deletions

View File

@@ -8,14 +8,23 @@ import { getErrorMessage, logError } from "../common.js";
export function createSettingsGetHandler() { export function createSettingsGetHandler() {
return (_req: Request, res: Response): void => { return (_req: Request, res: Response): void => {
const terminalService = getTerminalService(); try {
res.json({ const terminalService = getTerminalService();
success: true, res.json({
data: { success: true,
maxSessions: terminalService.getMaxSessions(), data: {
currentSessions: terminalService.getSessionCount(), maxSessions: terminalService.getMaxSessions(),
}, currentSessions: terminalService.getSessionCount(),
}); },
});
} catch (error) {
logError(error, "Get terminal settings failed");
res.status(500).json({
success: false,
error: "Failed to get terminal settings",
details: getErrorMessage(error),
});
}
}; };
} }

View File

@@ -181,8 +181,10 @@ export class TerminalService extends EventEmitter {
} }
// Normalize the path to resolve . and .. segments // Normalize the path to resolve . and .. segments
// This converts relative paths to absolute and cleans up the path // Skip normalization for WSL UNC paths as path.resolve would break them
cwd = path.resolve(cwd); if (!cwd.startsWith("//wsl")) {
cwd = path.resolve(cwd);
}
// Check if path exists and is a directory // Check if path exists and is a directory
try { try {

View File

@@ -408,6 +408,7 @@ describe("terminal-service.ts", () => {
describe("killSession", () => { describe("killSession", () => {
it("should kill existing session", () => { it("should kill existing session", () => {
vi.useFakeTimers();
vi.mocked(fs.existsSync).mockReturnValue(true); vi.mocked(fs.existsSync).mockReturnValue(true);
vi.mocked(fs.statSync).mockReturnValue({ isDirectory: () => true } as any); vi.mocked(fs.statSync).mockReturnValue({ isDirectory: () => true } as any);
vi.spyOn(process, "env", "get").mockReturnValue({ SHELL: "/bin/bash" }); vi.spyOn(process, "env", "get").mockReturnValue({ SHELL: "/bin/bash" });
@@ -416,8 +417,15 @@ describe("terminal-service.ts", () => {
const result = service.killSession(session.id); const result = service.killSession(session.id);
expect(result).toBe(true); expect(result).toBe(true);
expect(mockPtyProcess.kill).toHaveBeenCalled(); expect(mockPtyProcess.kill).toHaveBeenCalledWith("SIGTERM");
// Session is removed after SIGKILL timeout (1 second)
vi.advanceTimersByTime(1000);
expect(mockPtyProcess.kill).toHaveBeenCalledWith("SIGKILL");
expect(service.getSession(session.id)).toBeUndefined(); expect(service.getSession(session.id)).toBeUndefined();
vi.useRealTimers();
}); });
it("should return false for non-existent session", () => { it("should return false for non-existent session", () => {