如何 运行 和处理节点中子进程生成的错误
How to run and handle errors in child process spawn in node
我正在使用节点 child_process
在系统中生成进程。我可以使用在 data
、error
、end
和 [= 上触发的回调来控制 stdin
、stderr
等的 data
输出22=] 事件。
问题是当我像这里一样加载可执行文件时:
/**
* Load model in memory
*/
Executable.prototype.load = function() {
var self=this;
this.onExitCallback=null;
this.onDataCallback=null;
this.onErrorCallback=null;
return new Promise(function(resolve, reject) {
self.emitDeferred(EVENT_LOAD_START);
if( self.child ) {
self.emitDeferred(EVENT_LOAD_DONE);
return resolve(true);
}
self.onErrorCallback = function(error) {
return reject(error);
}
var args =[
'-input',
'-'
];
if( self._options.debug) console.log("load",args);
self.child=self.exec('runner', self._options.bin, args, self._options.child);
if(self._options.debug) self.child.stdout.pipe(process.stdout);
self.emitDeferred(EVENT_LOAD_DONE);
return resolve(true);
});
}//load
并且我在 error
回调中收到错误,我将调用 resolve
和 reject
,因为后者将由 onErrorCallback
触发,而第一个将在生成后立即被解雇,而我需要在保持 onErrorCallback
.
的同时避免 resolve
这是我的 exec
代码:
/**
* Execute child process
*/
this.exec = function(name,command,params,options) {
var self=this;
var _options = { detached: false };
for (var attrname in options) { _options[attrname] = options[attrname]; }
var created_time= ( new Date() ).toISOString();
var task = require('child_process').spawn(command, params, _options);
task.stdout.on('data', function(_data) {
if( self.onDataCallback ) self.onDataCallback.apply(self,[ new Buffer(_data,'utf-8').toString() ] );
});
task.on('error', function(error) {
if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
});
task.on('uncaughtException', function (error) {
if(self._options.debug) console.error("exec:%s pid:%s uncaughtException:\n",name,task.pid,error);
if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
});
task.stdout.on('end', function(data) {
if(self._options.debug) console.log("exec:%s end.",name);
});
task.stderr.on('data', function(data) {
//if(self._options.debug) console.log("exec:%s stderr:%s",name,data);
//if(!data) task.kill('SIGINT');
});
task.on('close', (code, signal) => {
if(self._options.debug) console.warn('task:%s pid:%s terminated due to receipt of signal:%s',name,task.pid,signal);
});
task.on('exit', function(code) {
if(self._options.debug) console.log("exec:%s exit.",name);
if (code != null && code != 0) {
var error=new Error();
error.description= command + ' ' + params.join(' ');
error.code=code;
if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
task.kill('SIGINT');
if( self.onExitCallback ) self.onExitCallback.apply(self,[error]);
} else {
// at exit explicitly kill exited task
task.kill('SIGINT');
if( self.onExitCallback ) self.onExitCallback.apply(self);
}
});
return task;
}//exec
和 send
将原始数据发送到 运行 子进程的代码:
/**
* Send data to child process
*/
this.send = function(data) {
this.child.stdin.setEncoding('utf-8');
this.child.stdin.write( data + '\r\n' );
}//send
所以要测试它就像
myExecutable.load()
.then(done => {
console.log("loaded %d", done);
})
.catch(error => {
console.error("error",error);
});
您可以使用 try{}catch(err){}
机制,您可以将 onErrorCallback 触发的代码放在 catch 中,从而避免解析,同时保持 onErrorCallback 完好无损。
我正在使用节点 child_process
在系统中生成进程。我可以使用在 data
、error
、end
和 [= 上触发的回调来控制 stdin
、stderr
等的 data
输出22=] 事件。
问题是当我像这里一样加载可执行文件时:
/**
* Load model in memory
*/
Executable.prototype.load = function() {
var self=this;
this.onExitCallback=null;
this.onDataCallback=null;
this.onErrorCallback=null;
return new Promise(function(resolve, reject) {
self.emitDeferred(EVENT_LOAD_START);
if( self.child ) {
self.emitDeferred(EVENT_LOAD_DONE);
return resolve(true);
}
self.onErrorCallback = function(error) {
return reject(error);
}
var args =[
'-input',
'-'
];
if( self._options.debug) console.log("load",args);
self.child=self.exec('runner', self._options.bin, args, self._options.child);
if(self._options.debug) self.child.stdout.pipe(process.stdout);
self.emitDeferred(EVENT_LOAD_DONE);
return resolve(true);
});
}//load
并且我在 error
回调中收到错误,我将调用 resolve
和 reject
,因为后者将由 onErrorCallback
触发,而第一个将在生成后立即被解雇,而我需要在保持 onErrorCallback
.
resolve
这是我的 exec
代码:
/**
* Execute child process
*/
this.exec = function(name,command,params,options) {
var self=this;
var _options = { detached: false };
for (var attrname in options) { _options[attrname] = options[attrname]; }
var created_time= ( new Date() ).toISOString();
var task = require('child_process').spawn(command, params, _options);
task.stdout.on('data', function(_data) {
if( self.onDataCallback ) self.onDataCallback.apply(self,[ new Buffer(_data,'utf-8').toString() ] );
});
task.on('error', function(error) {
if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
});
task.on('uncaughtException', function (error) {
if(self._options.debug) console.error("exec:%s pid:%s uncaughtException:\n",name,task.pid,error);
if( self.onErrorCallback ) self.onErrorCallback.apply(self,[error]);
});
task.stdout.on('end', function(data) {
if(self._options.debug) console.log("exec:%s end.",name);
});
task.stderr.on('data', function(data) {
//if(self._options.debug) console.log("exec:%s stderr:%s",name,data);
//if(!data) task.kill('SIGINT');
});
task.on('close', (code, signal) => {
if(self._options.debug) console.warn('task:%s pid:%s terminated due to receipt of signal:%s',name,task.pid,signal);
});
task.on('exit', function(code) {
if(self._options.debug) console.log("exec:%s exit.",name);
if (code != null && code != 0) {
var error=new Error();
error.description= command + ' ' + params.join(' ');
error.code=code;
if(self._options.debug) console.error("exec:%s pid:%d error:\n",name,task.pid,error);
task.kill('SIGINT');
if( self.onExitCallback ) self.onExitCallback.apply(self,[error]);
} else {
// at exit explicitly kill exited task
task.kill('SIGINT');
if( self.onExitCallback ) self.onExitCallback.apply(self);
}
});
return task;
}//exec
和 send
将原始数据发送到 运行 子进程的代码:
/**
* Send data to child process
*/
this.send = function(data) {
this.child.stdin.setEncoding('utf-8');
this.child.stdin.write( data + '\r\n' );
}//send
所以要测试它就像
myExecutable.load()
.then(done => {
console.log("loaded %d", done);
})
.catch(error => {
console.error("error",error);
});
您可以使用 try{}catch(err){}
机制,您可以将 onErrorCallback 触发的代码放在 catch 中,从而避免解析,同时保持 onErrorCallback 完好无损。