Skip to content

Commit 4de92ef

Browse files
committed
fix: async run error handling
1 parent 464f0b6 commit 4de92ef

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/command.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,18 @@ export class MassargCommand<Args extends ArgsObject = ArgsObject>
399399
process.on('unhandledRejection', handleRejection)
400400

401401
try {
402-
this.getArgs(argv, args, parent, true)
402+
const result = this.getArgs(argv, args, parent, true)
403+
404+
// Handle async run functions
405+
if (result instanceof Promise) {
406+
return result
407+
.then(() => cleanup())
408+
.catch((e) => {
409+
cleanup()
410+
this.handleError(e)
411+
})
412+
}
413+
403414
cleanup()
404415
} catch (e) {
405416
cleanup()
@@ -520,7 +531,7 @@ export class MassargCommand<Args extends ArgsObject = ArgsObject>
520531

521532
// no sub command found, run main command
522533
if (this._run) {
523-
this._run(this.args as Args, parent ?? this)
534+
return this._run(this.args as Args, parent ?? this)
524535
}
525536
} catch (e) {
526537
if (isZodError(e)) {

test/command.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,4 +309,20 @@ describe('onError', () => {
309309
expect(handler).toHaveBeenCalled()
310310
expect(handler.mock.calls[0][0].message).toBe('sub error')
311311
})
312+
313+
test('error handler catches async errors', async () => {
314+
const handler = vi.fn()
315+
const command = massarg(opts)
316+
.onError(handler)
317+
.main(async () => {
318+
await Promise.resolve()
319+
throw new Error('async error')
320+
})
321+
322+
await command.parse([])
323+
324+
expect(handler).toHaveBeenCalled()
325+
expect(handler.mock.calls[0][0].message).toBe('async error')
326+
expect(mockExit).toHaveBeenCalledWith(1)
327+
})
312328
})

0 commit comments

Comments
 (0)