# 🏅 Day 28 - 錯誤處理 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 連結貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
```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 / 答案 |
|:---------:|:-------------------------------------------------------------------:|
| bian_yang_mofa | [CodePen](https://codepen.io/cssf998811/pen/PwoZbPg?editors=0010)|
| sui_hsilan | [CodePen](https://codepen.io/suihsilan/pen/ByajQWB?editors=0010)|
| poyi | [CodePen](https://codepen.io/poyi-the-flexboxer/pen/qEBbmdp?editors=1010) |
|janetlai|[CodePen](https://codepen.io/eiddkqxz-the-builder/pen/XJWXarv?editors=1111)|
|adengg|[CodePen](https://codepen.io/Osases/pen/dPyGJRW?editors=0010)
|Tau|[CodePen](https://codepen.io/Tau-Hsu/pen/dPyGdNj?editors=0010)
|ZoeKang|[CodePen](https://codepen.io/byehywmx-the-animator/pen/qEBbKEV?editors=0010)
|JC|[CodePen](https://codepen.io/lifetimingwhisper/pen/ByaKKzE)
|helena|[CodePen](https://codepen.io/helena27/pen/WbNwEgL)
|sian|[CodePen](https://codepen.io/uxitysjl-the-flexboxer/pen/jEOrNgr)
|HarryKuo|[CodePen](https://codepen.io/harry_kuo/pen/XJWNarZ?editors=0010)|
|li wei-min|[CodePen](https://codepen.io/leewayne/pen/NPWgvjm)|
| hsin yu |[CodePen](https://codepen.io/tina2793778/pen/raNzBGY)|
|wuyuli_21403|[Codepen](https://codepen.io/Job-Wilhelm/pen/OPJjJNW?editors=0010)|