2016-11-22 80 views
2

我的Express應用程序中有一些錯誤處理,用於異步/等待功能,即。試圖集中處理未被捕獲的錯誤,以適當的狀態代碼/消息進行響應。Node.js Express unhandledRejection removeListener

我做像這樣:

const handleRejection = (res, reason) => { 
    const { code, message } = reason 
    console.trace() 
    logger.error(reason) 
    // use `res` to send response to client 
} 

app.use((req, res, next) => { 
    process.on('unhandledRejection', handleRejection.bind(this, res)) 
    next() 
}) 

process.on('SIGTERM',() => process.removeListener('unhandledRejection', handleRejection)) 

這工作得很好捕捉/處理錯誤,但是,我的日誌每次觸發一個錯誤的時間填滿。我不相信這個事件聽衆,process.on('unhandledRejection'),正在被正確刪除...

有沒有解決方案呢?

回答

2

看來你是在每個請求上附加一個新的事件處理程序。

然後,在SIGTERM試圖刪除的事件處理程序handleRejection這是從來沒有連接 - 你不重視handleRejectionhandleRejection.bind(this, res)返回不同的功能。

它看起來像你也可能通過綁定功能到每個請求的每個res對象泄漏內存。

這是處理錯誤的一種非常奇怪的方式。我甚至不確定這確實是你想要做的。你想添加如此多的事件hendler(每次向你的服務器發出一個請求),然後當你試圖退出你的服務器時,在SIGTERM上刪除所有這些事件?

+0

哦:(忘了app.use被擊中的每一個要求。黨,你能想到的任何其他方式在這個處理程序中訪問'res'對象? – benhowdle89

+0

基本上,我在整個路由處理程序中使用async/await,並且針對各種場景(驗證,數據庫錯誤等)拋出錯誤,並且我想要一箇中心位置來處理返回錯誤到客戶端 – benhowdle89

+0

因此,我讓'拋出新的錯誤'從Promise(async/await)冒泡到這個全局處理程序 – benhowdle89

0

這裏是我的一個快速的中間件解決方案,以unhandledRejection傳遞給主錯誤中間件

當然
// Handle unhandledRejection and pass error to next middleware 
    app.use(function (req, res, next) { 

     function unhandledRejection(reason, p) { 
      console.error('Possibly Unhandled Rejection at: Promise ', p, " reason: ", reason); 

      next(reason); 
     } 

     process.on('unhandledRejection', unhandledRejection); 

     // Manage to get information from the response too, just like Connect.logger does: 
     var end = res.end; 
     res.end = function (chunk, encoding) { 

      // Prevent MaxListener on process.events 
      process.removeListener('unhandledRejection', unhandledRejection); 
      res.end = end; 
      res.end(chunk, encoding); 
     }; 
     next(); 
    });