When the subprocess fails, the promise returned by execa()
is rejected with an ExecaError
instance. The error
has the same shape as successful results, with a few additional error-specific fields. error.failed
is always true
.
import {execa, ExecaError} from 'execa';
try {
const result = await execa`npm run build`;
console.log(result.failed); // false
} catch (error) {
if (error instanceof ExecaError) {
console.error(error.failed); // true
}
}
When the reject
option is false
, the error
is returned instead.
const resultOrError = await execa`npm run build`;
if (resultOrError.failed) {
console.error(resultOrError);
}
The subprocess fails when its exit code is not 0
. The exit code is available as error.exitCode
. It is undefined
when the subprocess fails to spawn or when it was terminated by a signal.
try {
await execa`npm run build`;
} catch (error) {
// Either non-0 integer or undefined
console.error(error.exitCode);
}
The subprocess can fail for other reasons. Some of them can be detected using a specific boolean property:
error.timedOut
:timeout
option.error.isCanceled
:cancelSignal
option.error.isMaxBuffer
:maxBuffer
option.error.isTerminated
: signal termination. This includes thetimeout
andcancelSignal
options since those terminate the subprocess with a signal. However, this does not include themaxBuffer
option.
Otherwise, the subprocess failed because either:
- An exception was thrown in a stream or transform.
- The command's executable file was not found.
- An invalid option was passed.
- There was not enough memory or too many subprocesses.
try {
await execa`npm run build`;
} catch (error) {
if (error.timedOut) {
handleTimeout(error);
}
throw error;
}
For better debugging, error.message
includes both:
- The command and the reason it failed.
- Its
stdout
,stderr
and other file descriptors' output, separated with newlines and not interleaved.
error.shortMessage
is the same but without stdout
/stderr
.
error.originalMessage
is the same but also without the command. This exists only in specific instances, such as when calling subprocess.kill(error)
, using the cancelSignal
option, passing an invalid command or option, or throwing an exception in a stream or transform.
try {
await execa`npm run build`;
} catch (error) {
console.error(error.originalMessage);
// The task "build" does not exist.
console.error(error.shortMessage);
// Command failed with exit code 3: npm run build
// The task "build" does not exist.
console.error(error.message);
// Command failed with exit code 3: npm run build
// The task "build" does not exist.
// [stderr contents...]
// [stdout contents...]
}
Safely handle failures by using automatic retries and exponential backoff with the p-retry
package.
import pRetry from 'p-retry';
import {execa} from 'execa';
const run = () => execa`curl -sSL https://sindresorhus.com/unicorn`;
console.log(await pRetry(run, {retries: 5}));
Next: 🏁 Termination
Previous: 🌐 Environment
Top: Table of contents