2017-03-12 43 views
2

我正在開發中的Node.js後端應用程序,我有以下問題遇到:當開發者調用函數的諾言象下面這樣:承諾 - 未處理拒絕掛起請求

mainRouter.get("/xD", async (req, res) => { 
    res.send(await this.fooService.foo()); 
}); 

有可能性this.fooService.foo()功能失敗(承諾拒絕)並且最終用戶將獲得請求超時。

我想確保開發人員的錯誤不會導致UnhandledPromiseRejectionWarning(並最終超時錯誤)。問題是如何配置應用程序以記錄錯誤並在出現UnhandleRejection時將狀態500返回給用戶。

我試了一下:

mainRouter.get("/xD", async (req, res) => { 
    try { 
     res.send(await this.fooService.foo()); 
    } catch (err) { 
     res.status(500).send("error"); 
    } 
}); 

上面的代碼會做的事情,但它從開發requiers寫在上面每條路由代碼,所以它不是很乾淨的解決方案。

我還試圖用錯誤的中間件:

mainRouter.use((err:any, req, res, next) => { 
    console.log(err); 
    res.status(500).send("Error"); 
}); 

但它不會趕上PromiseRejection

最後我創建的中間件這對於unhandledRecejtion事件寄存器功能處理:

mainRouter.use((req, res, next) => { 
    process.on('unhandledRejection', (reason, p) => { 
     console.log(reason); 
     res.status(500).send("Error"); 
    }); 
    next(); 
}); 

我不知道node.js中的流程事件是如何工作的,但是恐怕上面的代碼會導致場景中的問題:

  1. 首先請求生成未處理的承諾拒絕
  2. 其註冊的處理程序最後,將返回到用戶狀態的最新要求500
+0

「*從開發商requiers寫在上面每一個路線*代碼」 - 然後把一個'get'中的抽象本身 – Bergi

回答

0

爲什麼不只是提供一個包裝的功能,每個人都可以使用

async function wrapAsync(res, asyncFn) { 
    try { 
     res.send(await asyncFn()); 
    } catch (err) { 
     res.status(500).send("error"); 
    } 
} 

其中asyncFn是返回承諾的函數

然後其他開發者可以簡單地使用這種方式

mainRouter.get("/xD", async (req, res) => await wrapAsync(res, this.fooService.foo)); 

它也有可能改寫mainRouter.get,並提供一個更短的抽象

+0

你確定'await'可以用在非'async'函數中嗎? –

+0

你是對的,對不起,修好了 –

相關問題