diff --git a/src/dev-command.ts b/src/dev-command.ts index c87b8db..e99f51c 100644 --- a/src/dev-command.ts +++ b/src/dev-command.ts @@ -348,6 +348,12 @@ export async function runDevFetch(input: { }) } catch (error) { await input.auth.closeMock?.() + if (input.json) { + const message = error instanceof Error ? error.message : String(error) + input.io.stdout( + `${JSON.stringify({ type: 'build_error', message, ts: new Date().toISOString() }, null, 2)}\n`, + ) + } throw error } try { diff --git a/test/kody-dev.test.ts b/test/kody-dev.test.ts index 1e05c65..8d8f610 100644 --- a/test/kody-dev.test.ts +++ b/test/kody-dev.test.ts @@ -248,6 +248,52 @@ test('kody dev fetch rejects on a bundle error, prints it once, and closes the m } }) +test('kody dev fetch --json writes a build_error object to stdout on bundle failure', async () => { + const root = await mkdtemp(join(tmpdir(), 'kody-dev-broken-json-')) + try { + await writeFile( + join(root, 'package.json'), + JSON.stringify({ + name: '@local/broken-dev-json-package', + type: 'module', + kody: { id: 'broken-dev-json-package', app: { entry: './app/entry.ts' } }, + }), + ) + await mkdir(join(root, 'app')) + await writeFile( + join(root, 'app/entry.ts'), + 'export default { fetch() { return new Response("x" }\n', + ) + let stdout = '' + await assert.rejects( + runDevFetch({ + target: 'mock', + auth: { + token: 'mock', + apiUrl: 'http://127.0.0.1:9', + closeMock: async () => {}, + }, + path: '/', + cwd: root, + json: true, + io: { + stdout: (text) => { + stdout += text + }, + stderr: () => {}, + }, + }), + /app\/entry\.ts:1:52/, + ) + const event = JSON.parse(stdout) as { type: string; message: string; ts: string } + assert.equal(event.type, 'build_error') + assert.match(event.message, /app\/entry\.ts:1:52/) + assert.ok(typeof event.ts === 'string' && event.ts.length > 0) + } finally { + await rm(root, { recursive: true, force: true }) + } +}) + test('execute --target mock runs local code against the mock', async () => { const cache = await mkdtemp(join(tmpdir(), 'kody-exec-mock-')) const previous = process.env.KODY_CACHE_DIR