【Node.js】execSyncの返り値からstderrを取得してエラーハンドリングしたい
困ったこと
Node.jsのchild_process.execSync()
は他のexec()
やspawnSync()
などと違いstderr
を直接返してくれるわけではない。
import { execSync } from 'child_process';
function myCommand(command: string): string {
try {
return execSync(command).toString();
} catch (e: unknown) {
if (e instanceof Error) {
console.error(e.stderr.toString()); // Property 'stderr' does not exist on type 'Error'
}
throw e;
}
}
そのため例外処理の際にError
オブジェクトから取得することになるが、もちろんそのままでは取得させてくれない。
if (e instanceof Error) {
if (e instanceof ExecException) { // 'ExecException' only refers to a type, but is being used as a value here.
console.error(e.stderr.toString());
}
更に組み込みのExecException
も型情報しか提供されてないため利用できない。
解決法
function hasStderr(err: any): err is { stderr: Buffer } {
return !!err.stderr;
}
if (e instanceof Error) {
if (hasStderr(e)) {
console.error(e.stderr.toString());
}
やや苦肉の策ではあるがユーザ定義型ガードを使う。