# 🏅 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)|