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

[复制链接]
查看: 55|回复: 3
  • 慵懒
    2018-4-28 09:37
  • 发表于 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 | 显示全部楼层
    正需要,支持楼主大人了!
    回复

    使用道具 举报

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

    本版积分规则

     
     
    技术支持
    在线客服
    售后交流群瑞恩社区™售后</font><br><span>交流
    工作时间:
    8:00-18:00
    客服热线:
    15368564009
    微信扫一扫
    返回顶部 关注微信 下载APP 返回列表