# 🏅 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` 就需要跳出自訂的錯誤訊息。 `./service/appError.js` ```javascript= const appError = (httpStatus, errMessage, next) => { const error = new Error(errMessage); error.statusCode = httpStatus; error.isOperational = true; next(error); }; module.exports = appError; ``` `routes/posts.js` ```javascript= const appError = require("../service/appError"); 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); } }); ```