diff --git a/src/ink.tsx b/src/ink.tsx index 1162777a9..80610a7b2 100644 --- a/src/ink.tsx +++ b/src/ink.tsx @@ -27,7 +27,7 @@ export type Options = { debug: boolean; exitOnCtrlC: boolean; patchConsole: boolean; - waitUntilExit?: () => Promise; + initWaitUntilExit: boolean; }; export default class Ink { @@ -116,6 +116,13 @@ export default class Ink { options.stdout.off('resize', this.resized); }; } + + if (options.initWaitUntilExit) { + this.exitPromise = new Promise((resolve, reject) => { + this.resolveExitPromise = resolve; + this.rejectExitPromise = reject; + }); + } } resized = () => { diff --git a/src/render.ts b/src/render.ts index 748f4a4ff..25885541d 100644 --- a/src/render.ts +++ b/src/render.ts @@ -41,6 +41,13 @@ export type RenderOptions = { * @default true */ patchConsole?: boolean; + + /** + * Automatically initialize `waitUntilExit` method in order to catch synchronous errors. + * + * @default false + */ + initWaitUntilExit?: boolean; }; export type Instance = { @@ -80,6 +87,7 @@ const render: RenderFunction = (node, options): Instance => { debug: false, exitOnCtrlC: true, patchConsole: true, + initWaitUntilExit: false, ...getOptions(options) }; diff --git a/test/exit.tsx b/test/exit.tsx index 8c4f69950..0440eed2e 100644 --- a/test/exit.tsx +++ b/test/exit.tsx @@ -57,6 +57,14 @@ test.serial('exit with thrown error', async t => { t.true(output.includes('errored')); }); +test.serial( + 'exit with thrown error when initWaitUntilExit is true', + async t => { + const output = await run('exit-with-thrown-error-fix'); + t.true(output.includes('waitUntilExit catch: errored')); + } +); + test.serial('don’t exit while raw mode is active', async t => { await new Promise((resolve, _reject) => { const env: Record = { diff --git a/test/fixtures/exit-with-thrown-error-fix.tsx b/test/fixtures/exit-with-thrown-error-fix.tsx new file mode 100644 index 000000000..d87003c5b --- /dev/null +++ b/test/fixtures/exit-with-thrown-error-fix.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import {render} from '../../src/index.js'; + +const Test = () => { + throw new Error('errored'); +}; + +const app = render(, {initWaitUntilExit: true}); + +try { + await app.waitUntilExit(); +} catch (error: unknown) { + console.log(`waitUntilExit catch: ${(error as Error).message}`); +}