使用套接字在forked进程中优雅地处理未捕获的异常

时间:2016-01-13 20:56:17

标签: javascript node.js sockets fork child-process

我无法找到一种方法,以便在发送了套接字的分叉流程失败时如何正确处理这种情况。

以下是server.js的示例:

'use strict';

var http = require('http');
var fork = require('child_process').fork;

var srv = http.createServer(function (req, res) {
  var f = fork('./client.js');
  f.send('socket', res.socket);
});

srv.listen(7331, 'localhost', function () {
  console.log('server started');

  var req = http.request({
    port: 7331,
    path: '/'
  }, function (res) {
    res.setEncoding('utf8');
    var body = '';
    res.on('data', function (chunk) {
      body += chunk;
    });
    res.on('end', function () {
      console.log('RESPONSE', res.statusCode, res.headers, body);
    });
  });
  req.on('error', function (e) {
    console.log('REQUEST ERROR', e.stack);
  });
  req.end();
});

client.js

throw new Error('Client error');

我得到以下输出:

    server started
client.js:1
(function (exports, require, module, __filename, __dirname) { throw new Error('Client Error');
                                                              ^

Error: Client Error
    at Object.<anonymous> (client.js:1:69)
    at Module._compile (module.js:425:26)
    at Object.Module._extensions..js (module.js:432:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:457:10)
    at startup (node.js:136:18)
    at node.js:972:3
REQUEST ERROR Error: socket hang up
    at createHangUpError (_http_client.js:209:15)
    at Socket.socketOnEnd (_http_client.js:294:23)
    at emitNone (events.js:72:20)
    at Socket.emit (events.js:166:7)
    at endReadableNT (_stream_readable.js:905:12)
    at doNTCallback2 (node.js:450:9)
    at process._tickCallback (node.js:364:17)

是否可以在给定情况下处理分叉进程中的未捕获异常,并生成包含状态代码和正文中错误描述的友好响应?

我尝试过的事情:

  1. 订阅了close中孩子的server.js个活动,并发送了回复但没有运气 - This socket is closed.被抛出
  2. 在发出错误之前在client.js做了一些准备工作:订阅了uncaughtException并发送了一些响应数据 - 仍然是socket hang up而没有回应

1 个答案:

答案 0 :(得分:1)

由于此处缺少活动,我在nodejs repo https://github.com/nodejs/node/issues/4745中发布了问题,引起了nodejs贡献者的注意。

总结一下:在父进程中使用套接字是不可能发送给子进程的,因为只要调用send()就会销毁它。

因此,解决问题的唯一方法是在错误发生之前在client.js中做一些准备工作。我在尝试#2 中表示我做到了这一点,但也许我做错了......使用以下client.js代码,一切正常:

'use strict';

let socket;

process.on('uncaughtException', function (e) {
  socket.write(`HTTP/1.1 500 OK\nContent-Type: text/html\nContent-Length: ${e.message.length}\n\n${e.message}`);
});

process.on('message', function (type, s) {
  socket = s;
  routine();
});


function routine() {
  throw new Error('Client error');
}