記錄幾個node.js錯誤及解決方案

來源:互聯網
上載者:User

記錄幾個node.js錯誤及解決方案

 幾個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

另外附上在Google的過程中看到了另外一個類似的錯誤。這是當你為多種情況做 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 就正常了.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.