【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());}やや苦肉の策ではあるがユーザ定義型ガードを使う。
参考