diff --git a/index.d.ts b/index.d.ts index f32ac41586..2050cfa874 100644 --- a/index.d.ts +++ b/index.d.ts @@ -302,6 +302,13 @@ declare namespace execa { The error message. */ message: string; + + /** + Original error message. This is `undefined` unless the child process exited due to an `error` event or a timeout. + + The `message` property contains both the `originalMessage` and some additional information added by Execa. + */ + originalMessage?: string; } interface ExecaError diff --git a/index.test-d.ts b/index.test-d.ts index f1261b34da..74ff581d73 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -40,6 +40,7 @@ try { expectType(execaError.isCanceled); expectType(execaError.killed); expectType(execaError.signal); + expectType(execaError.originalMessage); } try { @@ -69,6 +70,7 @@ try { expectError(execaError.isCanceled); expectType(execaError.killed); expectType(execaError.signal); + expectType(execaError.originalMessage); } execa('unicorns', {cleanup: false}); diff --git a/lib/error.js b/lib/error.js index c746fbf948..f071c5f2ba 100644 --- a/lib/error.js +++ b/lib/error.js @@ -53,6 +53,7 @@ const makeError = ({ const message = `Command ${prefix}: ${command}`; if (error instanceof Error) { + error.originalMessage = error.message; error.message = `${message}\n${error.message}`; } else { error = new Error(message); diff --git a/readme.md b/readme.md index 6b42383fc1..44b9ee2a0a 100644 --- a/readme.md +++ b/readme.md @@ -277,6 +277,14 @@ Type: `string | undefined` The signal that was used to terminate the process. +#### originalMessage + +Type: `string | undefined` + +Original error message. This is `undefined` unless the child process exited due to an `error` event or a timeout. + +The `message` property contains both the `originalMessage` and some additional information added by Execa. + ### options Type: `object` diff --git a/test/error.js b/test/error.js index a009b041fe..4a8288b605 100644 --- a/test/error.js +++ b/test/error.js @@ -163,3 +163,8 @@ errorMessage.title = (message, expected) => `error.message matches: ${expected}` test(errorMessage, /Command failed with exit code 2.*: exit 2 foo bar/, 2, 'foo', 'bar'); test(errorMessage, /Command failed with exit code 3.*: exit 3 baz quz/, 3, 'baz', 'quz'); + +test('Original error message is kept', async t => { + const {originalMessage} = await t.throwsAsync(execa('wrong command')); + t.is(originalMessage, 'spawn wrong command ENOENT'); +});