History

Fix keybindings parse error wrapping behavior

Julius Marminge committed 8 months ago

Commit e52db0b1 parent 71d8f742 files · +38 −5Browse files

Unified · Split

2 files
  1. apps/server/src/keybindings.test.ts +25 −0
  2. apps/server/src/keybindings.ts +13 −5
apps/server/src/keybindings.test.ts+25−0
@@ -171,6 +171,31 @@ describe("server keybindings", () => { · 170 unmodified lines
171171 expect(fs.readFileSync(configPath, "utf8")).toBe("{ not-json");
172172 });
173173
174+ it("reports non-array config parse errors without duplicate prefix", () => {
175+ const fakeHome = makeTempDir("t3code-keybindings-non-array-");
176+ const configDir = path.join(fakeHome, ".t3");
177+ fs.mkdirSync(configDir, { recursive: true });
178+ const configPath = path.join(configDir, "keybindings.json");
179+ fs.writeFileSync(configPath, JSON.stringify({ key: "mod+j", command: "terminal.toggle" }), "utf8");
180+ vi.spyOn(os, "homedir").mockReturnValue(fakeHome);
181+
182+ expect(() =>
183+ upsertKeybindingRule(logger, {
184+ key: "mod+shift+r",
185+ command: "script.run-tests.run",
186+ }),
187+ ).toThrow(new RegExp(`Unable to parse keybindings config at ${configPath}: expected JSON array`));
188+
189+ expect(() =>
190+ upsertKeybindingRule(logger, {
191+ key: "mod+shift+r",
192+ command: "script.run-tests.run",
193+ }),
194+ ).not.toThrow(
195+ new RegExp(`Unable to parse keybindings config at ${configPath}: Unable to parse keybindings config at`),
196+ );
197+ });
198+
174199 it("cleans up temp files when atomic keybinding write fails", () => {
175200 const fakeHome = makeTempDir("t3code-keybindings-atomic-");
176201 const configDir = path.join(fakeHome, ".t3");
apps/server/src/keybindings.ts+13−5
@@ -292,6 +292,12 @@ const DEFAULT_RESOLVED_KEYBINDINGS = compileDefaultKeybindings(); · 291 unmodified lines
292292 const KEYBINDINGS_CONFIG_PATH = path.join(".t3", "keybindings.json");
293293 const MAX_KEYBINDINGS = 256;
294294
295+class KeybindingsConfigParseError extends Error {
296+ constructor(configPath: string, detail: string, options?: { cause?: unknown }) {
297+ super(`Unable to parse keybindings config at ${configPath}: ${detail}`, options);
298+ }
299+}
300+
295301 function resolveKeybindingsConfigPath(): string {
296302 return path.join(os.homedir(), KEYBINDINGS_CONFIG_PATH);
297303 }
@@ -308,7 +314,7 @@ function loadCustomKeybindingsConfig( · 10 unmodified lines
308314 const parsed = JSON.parse(raw) as unknown;
309315 if (!Array.isArray(parsed)) {
310316 if (options?.throwOnUnreadableConfig) {
311− throw new Error(`Unable to parse keybindings config at ${configPath}: expected JSON array`);
317+ throw new KeybindingsConfigParseError(configPath, "expected JSON array");
312318 }
313319 logger.warn("ignoring keybindings config with unsupported format; expected array", {
314320 path: configPath,
@@ -343,10 +349,12 @@ function loadCustomKeybindingsConfig( · 28 unmodified lines
343349 return [];
344350 }
345351 if (options?.throwOnUnreadableConfig) {
346− throw new Error(
347− `Unable to parse keybindings config at ${configPath}: ${
348− error instanceof Error ? error.message : String(error)
349− }`,
352+ if (error instanceof KeybindingsConfigParseError) {
353+ throw error;
354+ }
355+ throw new KeybindingsConfigParseError(
356+ configPath,
357+ error instanceof Error ? error.message : String(error),
350358 { cause: error },
351359 );
352360 }