45IT.COM- 电脑学习从此开始!
DIY硬件教程攒机经验装机配置
设计Photoshop网页设计特效
系统注册表DOS系统命令其它
存储主板显卡外设键鼠内存
维修显卡CPU内存打印机
WinXPVistaWin7unix/linux
CPU光驱电源/散热显示器其它
修技主板硬盘键鼠显示器光驱
办公ExcelWordPowerPointWPS
编程数据库CSS脚本PHP
网络局域网QQ服务器
软件网络系统图像安全
页面导航: 首页 > 设计学院 > 网络编程 > javascript >

记录几个node.js错误及解决方案

电脑软硬件应用网 45IT.COM 时间:2015-07-21 22:26 作者:佚名
在工作中遇到的几个node.js常见的几个错误,主要错误有:EBADF, write; EBADF, close; EBADF, bad file descriptor; stdout maxBuffer exceeded。

几个node.js错误及解决办法整理如下

node.js Error: EBADF, write

最近工作写了个小项目,本以为能好好喝下茶,可是让人想掀桌的报错出现了。

fs.js:77
      throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
            ^
Error: EBADF, write
    at Error (native)

WTF?! fs.js: 77? 这是要我去看内核源代码?好在项目还不大,拆拆更健康。花了半天的时间之后大概是清楚了。

首先是 Error 的名字 EBADF 其意义是 bad file descriptor 错误的文件描述符。
而 Error: EBADF, write 表示往错误的文件描述符里面写数据了。

出现这个BUG的场景简而言之,是有一个 .on('data') 事件拿到数据往 fd 里面写,这个时候某个操作抛了 error 我在处理error 的时候 close 了这个 fd,而另外一边去还在触发 data 事件想往这个(已经被我 close 的)fd里面写数据。如下:

// ...
 
var fd = fs.openSync(path, 'w');
 
test.on('data', function(data) {
    fs.write(fd, data);
});
 
test.on('end', function() {
    fs.close(fd);
});
 
// 在 end 之前 close 就会出现 Error: EBADF, write
setTimeout(function() {
    fs.close(fd);
}, 10);
 
// ...

解决方案:所以我们排查好出现 fs.close 关闭文件描述符的地方,确保 close 之后不会再有 read/write 。


Error: EBADF, close

另外附上在谷歌的过程中看到了另外一个类似的错误。这是当你为多种情况做 fs.close(fd); 的处理,然而不幸的是,多个情况被都触发, fs.close(fd) 调用了多遍,同样也会出现 EBADF 错误。这样就能出现:

test.on('end', function() {
    fs.close(fd);
    fs.close(fd); // 多调用了一次就会出现
});

不友好的报错


fs.js:77
      throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
            ^
Error: EBADF, close
    at Error (native)

解决方案:依旧是排查 fs.close,只不过这次是要保证多种处理不会反复执行 fs.close ,或者你可以使用 try/catch 来无视它。

Error: EBADF, bad file descriptor

最后,当 fd 失效以后进行 read 操作的话,我还以为会出现 Error: EBADF, read 结果并没有。以下是尝试出现BUG的代码:


// ...
 
fs.closeSync(fd);
fs.readSync(fd, new Buffer(1024), 0, 1024);
 
// ...

不过这个报错会友好很多,有将其调用栈打出来。

fs.js:552
  var r = binding.read(fd, buffer, offset, length, position);
                  ^
Error: EBADF, bad file descriptor
    at Error (native)
    at Object.fs.readSync (fs.js:552:19)
    at command.<anonymous> (/Users/Lellansin/Documents/workspace/node/test-server/app/services/TestService.js:40:6)
    at command.emit (events.js:110:17)
    at ChildProcess.emit (events.js:129:20)
    at maybeClose (child_process.js:1015:16)
    at Socket.<anonymous> (child_process.js:1183:11)
    at Socket.emit (events.js:107:17)
    at Pipe.close (net.js:485:12)

解决方案:看错误栈去改代码就好了。。


node.js Error: stdout maxBuffer exceeded

在使用 child_process 模块中的 exec 、execFile、spawnSync、execFileSync、execSync 方法时需要注意其 options 参数中的 maxBuffer 项。

以上方法在执行时会在内存中建一个 buffer 来缓冲组合所有的输出数据,而 maxBuffer 则是指定该 buffer 大小的地方。如果输出超过指定的大小则会报 maxBuffer exceeded 的错误。

解决方案是执行的时候估计好大小,设置更大的 maxBuffer:

var exec = require('child_process').exec;
 
var child = exec('ls -lah', {
    encoding: 'utf8',
    timeout: 0,
    maxBuffer: 5000 * 1024, // 默认 200 * 1024
    killSignal: 'SIGTERM'
}, function(err, stdout, stderr) {
    console.log(stdout);
});

或者是用 spawn 的 .on('data') 事件触发时,手动拼接数据到 .on('close') 事件触发的时候获得完整数据。


pomelo Cannot call method 'forwardMessage' of undefined

报错信息:
[2014-09-10 14:32:45.315] [DEBUG] pomelo - [E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\components\
connector.js] [connector-server-1] handleMessage session id: 1, msg: {"id":10,"type":0,"compressRoute":0,"route":"user.u
serHandler.login","body":"{username:'alan_1', password:'123456', dev_id:'6984654'}"}
[2014-09-10 14:32:45.320] [ERROR] pomelo - [E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\server\serv
er.js] fail to forward message:TypeError: Cannot call method 'forwardMessage' of undefined
    at doForward (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\server\server.js:334:50)
    at dispatch (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\server\server.js:103:7)
    at next (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\common\service\filterService.js:50:7)
    at Service.beforeFilter (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\common\service\filterServi
ce.js:65:3)
    at beforeFilter (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\server\server.js:242:8)
    at pro.globalHandle (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\server\server.js:112:3)
    at Component.globalHandle (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\components\server.js:74:
14)
    at handleMessage (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\components\connector.js:295:15)
    at null.<anonymous> (E:\svn\xjmh\trunk\src\server\game-server\node_modules\pomelo\lib\components\connector.js:239:5)
 
    at EventEmitter.emit (events.js:95:17)

Pomelo Club 上有些说法是前端服务器将消息转发到其它服务器过程中出现问题,rpc失败。或者可能是 handler 拼错。
博主检查发现在 servers.json 中普通 server 如果配置了 "frontend":true 就会出现这个问题. 尝试把 frontend 去掉或者改成 false 就正常了.

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
推荐知识