# 🏅 Day 21 - 錯誤處理 middleware、自訂錯誤訊息 ### 錯誤處理(error handler)middleware 在 `app.js` 可以撰寫錯誤處理的程式碼,當錯誤發生時,就會進入下方錯誤處理 middleware 回傳我們自訂的錯誤訊息 `app.js` ```javascript= // 錯誤處理的 middleware 相較一般 middleware 會多一個 err 引數 app.use((err, req, res, next) => { err.statusCode = err.statusCode || 500; err.status = err.status || 'error'; res.status(err.statusCode).json({ status: err.status, message: err.message }); }); ``` ### 自訂錯誤訊息 我們可以另外新增自定義錯誤訊息的模組,在預期使用者可能會出錯的地方驗證錯誤(像是:xx 資料未填寫時,即可跳出自訂錯誤訊息) 撰寫流程: 自訂一個 appError function,將狀態碼及自訂錯誤訊息及 next 參數傳到 function 中。 使用 `new Error()` 帶入自訂錯誤訊息,建立 Error 物件,並設定 Error 回傳的資訊:`statusCode` 狀態碼、`isOperational` ,其中 `isOperational` 代表是否為**可預期**的錯誤,因是自訂的錯誤,通常都會設定為 true(可預期) 最後使用 `next()` 將 Error 交給 `app.js` 中的錯誤處理 middleware 回傳錯誤訊息 **範例**(較完整範例可觀看此 [GitHub](https://github.com/gonsakon/express-week4-sample/blob/week5/service/appError.js)) `appError.js` ```javascript const appError = (httpStatus, errMessage, next) => { const error = new Error(errMessage); error.statusCode = httpStatus; error.isOperational = true; next(error); }; module.exports = appError; ``` ### 參考資源 - [Error - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) - [Express 錯誤處理](https://expressjs.com/zh-tw/guide/error-handling.html) 題目 --- 請嘗試將以下 POST 路由中的程式碼使用 `appError()` 加入以下自訂錯誤資訊 > statusCode: 400 > message: '欄位未填寫正確:貼文內容為必填' 當新增貼文時,若使用者未輸入內容 `content` 就需要跳出自訂的錯誤訊息。 `routes/posts.js` ```javascript= router.post('/', async (req, res, next) => { try { const data = req.body; if (!data.content) { // appError 自訂錯誤回饋 return next(...); } const newPost = await Post.create( { user: data.user, content: data.content, tags: data.tags, type: data.type } ); res.status(200).json({ status: 'success', data: newPost }); } catch (error) { next(error); } }); ``` ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: ```javascript= router.post('/', async (req, res, next) => { try { const data = req.body; if (!data.content) { // appError 自訂錯誤回饋 return next(appError(400, '欄位未填寫正確:貼文內容為必填', next)); } const newPost = await Post.create( { user: data.user, content: data.content, tags: data.tags, type: data.type } ); res.status(200).json({ status: 'success', data: newPost }); } catch (error) { next(error); } }); ``` --> 回報區 --- <!-- 將答案貼至下方表格內,格式: | Discord 暱稱 | [CodePen](連結) | --> | Discord | CodePen / 答案 | |:---------:|:-------------------------------------------------------------------:| | xxx | [CodePen]() | | 苡安 | [hackmd](https://hackmd.io/@L7K9-66lSeagS28AP0_GjQ/HkubhPeM0) | | Aida | [CodePen](https://codepen.io/ada23410/pen/dyLELGK?editors=0010) | | jenny7532 | [CodePen](https://codepen.io/wei-chen-wu/pen/ZEZNZrJ) | | Chia pin| [CodePen](https://codepen.io/joker-cat/pen/KKYLLgZ) | | william威良 | [CodePen](https://codepen.io/snowman12320/pen/LYvoKdL?editors=1010) | | wei | [CodePen](https://hackmd.io/@xu7yoa5cSsqaron7h9XhUw/H1yhk0xf0) | | 2魚 | [CodePen](https://codepen.io/ijrekmsn-the-sans/pen/vYMqNdp) | |Mei|[CodePen](https://codepen.io/l_umei/pen/mdgZEQK)| |Lobinda|[HackMD](https://hackmd.io/@Lobinda/H1HaZn-f0)| |ej_chuang|[HackMD](https://codepen.io/EJChuang/pen/PogrMJg)| | runweiting |[HackMD](https://codepen.io/weiting14/pen/XWQvMep)| | Tiya |[CodePen](https://codepen.io/Tiya_blank/pen/rNbQPbY)| | tung030374 |[CodePen](https://codepen.io/tung__u/pen/GRLVPKx?editors=0010)| | william_hsu |[CodePen](https://codepen.io/william8815/pen/yLWBxMm)| | Hank |[CodePen](https://codepen.io/tw1720/pen/jOoOPPP)| |Benson|[CodePen](https://codepen.io/nosneb83/pen/XWQLgWL)|