| author | |
| committer | |
| log | b0b7b38da1dc4b19833d13f84eb907b1e2adfb63 |
| tree | 121145229de1ac152b0473fbcd055349ad9c1af5 |
| parent | fd3b96b487a9aac8a011c27f977067d63d942ac1 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>2 files changed, 33 insertions(+), 2 deletions(-)
apps/server/src/processRunner.test.ts+19-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | import { describe, expect, it } from "vitest"; |
| 2 | 2 | |
| 3 | import { runProcess } from "./processRunner.ts"; | |
| 3 | import { isWindowsCommandNotFound, runProcess } from "./processRunner.ts"; | |
| 4 | 4 | |
| 5 | 5 | describe("runProcess", () => { |
| 6 | 6 | it("fails when output exceeds max buffer in default mode", async () => { |
| ... | ... | @@ -21,3 +21,21 @@ describe("runProcess", () => { |
| 21 | 21 | expect(result.stderrTruncated).toBe(false); |
| 22 | 22 | }); |
| 23 | 23 | }); |
| 24 | ||
| 25 | describe("isWindowsCommandNotFound", () => { | |
| 26 | it("matches the localized German cmd.exe error text", () => { | |
| 27 | const originalPlatform = process.platform; | |
| 28 | Object.defineProperty(process, "platform", { value: "win32", configurable: true }); | |
| 29 | ||
| 30 | try { | |
| 31 | expect( | |
| 32 | isWindowsCommandNotFound( | |
| 33 | 1, | |
| 34 | "wird nicht als interner oder externer Befehl, betriebsfahiges Programm oder Batch-Datei erkannt", | |
| 35 | ), | |
| 36 | ).toBe(true); | |
| 37 | } finally { | |
| 38 | Object.defineProperty(process, "platform", { value: originalPlatform, configurable: true }); | |
| 39 | } | |
| 40 | }); | |
| 41 | }); |
apps/server/src/processRunner.ts+14-1| ... | ... | @@ -37,10 +37,23 @@ function normalizeSpawnError(command: string, args: readonly string[], error: un |
| 37 | 37 | return new Error(`Failed to run ${commandLabel(command, args)}: ${error.message}`); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | const WINDOWS_COMMAND_NOT_FOUND_PATTERNS = [ | |
| 41 | /is not recognized as an internal or external command/i, | |
| 42 | /n.o . reconhecido como um comando interno/i, | |
| 43 | /non . riconosciuto come comando interno o esterno/i, | |
| 44 | /n.est pas reconnu en tant que commande interne/i, | |
| 45 | /no se reconoce como un comando interno o externo/i, | |
| 46 | /wird nicht als interner oder externer befehl/i, | |
| 47 | ] as const; | |
| 48 | ||
| 49 | function hasWindowsCommandNotFoundMessage(output: string): boolean { | |
| 50 | return WINDOWS_COMMAND_NOT_FOUND_PATTERNS.some((pattern) => pattern.test(output)); | |
| 51 | } | |
| 52 | ||
| 40 | 53 | export function isWindowsCommandNotFound(code: number | null, stderr: string): boolean { |
| 41 | 54 | if (process.platform !== "win32") return false; |
| 42 | 55 | if (code === 9009) return true; |
| 43 | return /is not recognized as an internal or external command/i.test(stderr); | |
| 56 | return hasWindowsCommandNotFoundMessage(stderr); | |
| 44 | 57 | } |
| 45 | 58 | |
| 46 | 59 | function normalizeExitError( |