node.jstypescriptaws-clichild-process

Casting exception type on child_process exec - NodeJS, Typescript


Example code:

const execPromise = util.promisify(exec);
try {
    const { stdout } = await execPromise(cliCommand);
} catch (error) {
    if (error instanceof S3ServiceException) {
      // error is of type string so this if-statement is always false
      console.log(error.message);
    }
}

I'm using AWS s3api CLI head-object command to check existence of a object in the bucket through NodeJS child_process.exec function. If there is no object in the bucket, s3api throws an error like:

Error: Command failed: aws s3api head-object --bucket bucket --key key

An error occurred (404) when calling the HeadObject operation: Not Found

    at ChildProcess.exithandler (node:child_process:419:12)
    at ChildProcess.emit (node:events:513:28)
    at ChildProcess.emit (node:domain:489:12)
    at maybeClose (node:internal/child_process:1091:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:302:5) {
  code: 254,
  killed: false,
  signal: null,
  cmd: 'aws s3api head-object --bucket bucket_name --key keyname'
}

Now, I suppose this error is an instanceof of a exception class (e.g. S3ServiceException).

The problem:

exec function throws an error as plain string and I can't do the needed cast/instanceof check.

Is there a way to cast/check what instanceof is an exception thrown out of the exec function?


Solution

  • Unfortunately, using exec can only result in string-type errors because it runs your command as a separate process which results in string outputs. The error being thrown and caught in your example is simply the stderr output of the command.

    My recommendation is to use the AWS SDK to run your commands: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html. Using that will not only allow you to check the types of your errors, but it will also give you native returns (i.e. you won't have to post-process stdout to get your return value).

    If you absolutely can not use the AWS SDK and need to make your existing setup working, you can always use regex to check for specific errors but that is a very fragile setup.