From 6f80386939c780bce1e0341a48c016db2874072e Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Tue, 3 Feb 2026 17:31:08 -0800 Subject: [PATCH] feat: better errors --- src/services/gitService.ts | 17 +++++++++++++++- test/services/gitService.spec.ts | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/services/gitService.ts b/src/services/gitService.ts index 47c259d..ed456c1 100644 --- a/src/services/gitService.ts +++ b/src/services/gitService.ts @@ -120,7 +120,22 @@ const updatePackageAndCommit = async( void logger.log("info", `Running pnpm install for ${packageName}...`); const pnpmPath = "/home/naomi/.local/share/pnpm/pnpm"; - await execAsync(`${pnpmPath} install --no-frozen-lockfile`, { cwd: repoPath }); + try { + await execAsync(`${pnpmPath} install --no-frozen-lockfile`, { cwd: repoPath }); + } catch (pnpmError: unknown) { + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Catch blocks receive unknown, cast needed to access stderr/stdout */ + const details = pnpmError as Error & { stderr?: string; stdout?: string }; + + /* eslint-disable capitalized-comments -- v8 coverage requires lowercase */ + /* v8 ignore next 5 -- @preserve */ + /* eslint-enable capitalized-comments -- Re-enable rule */ + /* eslint-disable @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- Intentionally using || to treat empty strings as falsy */ + const errorMessage = details.stderr || details.stdout || details.message; + /* eslint-enable @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing -- Re-enable rules */ + + void logger.log("info", `pnpm install failed: ${errorMessage}`); + throw pnpmError; + } await runGitCommand(logger, repoPath, "git add package.json pnpm-lock.yaml"); const commitMessage = `deps: update ${packageName} to ${targetVersion}`; diff --git a/test/services/gitService.spec.ts b/test/services/gitService.spec.ts index 14786a5..1975d33 100644 --- a/test/services/gitService.spec.ts +++ b/test/services/gitService.spec.ts @@ -363,4 +363,38 @@ describe("gitService", () => { expect(writtenContent.dependencies["test-package"]).toBe("2.0.0"); expect(writtenContent.devDependencies["test-package"]).toBe("2.0.0"); }); + + it("should log pnpm error details when install fails", async() => { + expect.assertions(2); + mockExecAsync.mockImplementation((command: string) => { + if (command.includes("pnpm install")) { + const error = new Error("pnpm failed") as Error & { + stderr: string; + stdout: string; + }; + error.stderr = "ERR_PNPM_NO_MATCHING_VERSION"; + error.stdout = ""; + return Promise.reject(error); + } + return Promise.resolve({ stderr: "", stdout: "" }); + }); + vi.mocked(readFile).mockResolvedValue(JSON.stringify({ + dependencies: { "test-package": "1.0.0" }, + })); + vi.mocked(writeFile).mockResolvedValue(undefined); + const { createOrUpdateBranch } = await import("../../src/services/gitService.js"); + const mockClonedRepo = createMockClonedRepo(); + const result = await createOrUpdateBranch({ + branchName: "dependencies/update-test-package", + clonedRepo: mockClonedRepo, + logger: mockLogger, + packageName: "test-package", + targetVersion: "2.0.0", + }); + expect(result.status).toBe("failed"); + expect(mockLogger.log).toHaveBeenCalledWith( + "info", + expect.stringContaining("ERR_PNPM_NO_MATCHING_VERSION"), + ); + }); });