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

[复制链接]
查看: 285|回复: 7
发表于 2018-4-3 09:45:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

几个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. (/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. (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:svnxjmhtrunksrcservergame-servernode_modulespomelolibcomponents
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:svnxjmhtrunksrcservergame-servernode_modulespomelolibserverserv
er.js] fail to forward message:TypeError: Cannot call method 'forwardMessage' of undefined
    at doForward (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibserverserver.js:334:50)
    at dispatch (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibserverserver.js:103:7)
    at next (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibcommonservicefilterService.js:50:7)
    at Service.beforeFilter (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibcommonservicefilterServi
ce.js:65:3)
    at beforeFilter (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibserverserver.js:242:8)
    at pro.globalHandle (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibserverserver.js:112:3)
    at Component.globalHandle (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibcomponentsserver.js:74:
14)
    at handleMessage (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibcomponentsconnector.js:295:15)
    at null. (E:svnxjmhtrunksrcservergame-servernode_modulespomelolibcomponentsconnector.js:239:5)

    at EventEmitter.emit (events.js:95:17)

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


发表于 2018-5-1 11:20:16 | 显示全部楼层
我只是路过打酱油的
回复

使用道具 举报

发表于 2018-6-26 17:56:36 | 显示全部楼层
确实是难得好帖啊,顶先
回复

使用道具 举报

发表于 2018-7-4 18:44:12 | 显示全部楼层
正需要,支持楼主大人了!
回复

使用道具 举报

发表于 2019-2-3 21:27:18 | 显示全部楼层
额,看不懂在说神马~@_@
回复

使用道具 举报

发表于 2019-2-20 01:37:52 | 显示全部楼层
这个帖一般般,还可以哦。
回复

使用道具 举报

发表于 2019-2-20 12:36:59 | 显示全部楼层
珍惜生命,果断回帖。
回复

使用道具 举报

发表于 2019-2-20 19:16:40 | 显示全部楼层
我只是路过打酱油的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

 
 
工作时间:
8:00-18:00
客服热线:
15368564009
客服微信