---
# System prepended metadata

title: "\U0001F3C5 Day 23 - development 及 production 環境變數指令、客製錯誤訊息"
tags: [Node.js 直播班 - 2023 春季班]

---

---
tags: Node.js 直播班 - 2023 春季班
---

# 🏅 Day 23 - development 及 production 環境變數指令、客製錯誤訊息

由於通常不會將開發時遇到的詳細錯誤資訊（如 error.stack）呈現在客戶端，避免過多資訊暴露而有資安疑慮，因此會區分 development 及 production 模式下的錯誤訊息

可在錯誤處理 (error handler) middleware 判斷 Node.js 環境變數
`process.env.NODE_ENV` 為 `dev` 或是 `production`（下方 error handler 範例 31 及 33 行），以提供不同錯誤處理


:::spoiler error handler 範例（點擊展開）

```javascript=
// 自己設定的 err 錯誤 
const resErrorProd = (err, res) => {
  if (err.isOperational) {
    res.status(err.statusCode).json({
      status: err.status,
      message: err.message
    });
  } else {
    // log 紀錄
    console.error('出現重大錯誤', err);
    // 送出罐頭預設訊息
    res.status(500).json({
      status: 'error',
      message: '系統錯誤，請恰系統管理員'
    });
  }
};
// 開發環境錯誤
const resErrorDev = (err, res) => {
  res.status(err.statusCode).json({
    status: err.status,
    message: err.message,
    error: err,
    stack: err.stack
  });
};
// error handler
app.use(function(err, req, res, next) {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';
  if (process.env.NODE_ENV === 'dev') {
    resErrorDev(err, res);
  } else if (process.env.NODE_ENV === 'production') {
    if(err.isAxiosError == true){
      err.message = "axios 連線錯誤";
      err.isOperational = true;
      return resErrorProd(err, res)
    } else if (err.name === 'ValidationError'){
      // mongoose 資料辨識錯誤
      err.isOperational = true;
      return resErrorProd(err, res)
    }
    resErrorProd(err, res)
  }
});
```
:::
範例中分別以 `resErrorDev(err, res)` `resErrorProd(err, res)` 回傳不同模式回饋錯誤的 JSON 資料
Production 模式會依據是否為預期 client 端可能會出現的錯誤，決定是否回傳提示 client 端錯誤處，若為 server 端需處理的錯誤，則回傳「系統錯誤，請恰系統管理員」的文字，不需回傳相關錯誤資訊


--

設定好不同模式的錯誤回饋後，在 package.json 設定設定執行指令，測試不同模式是否有正確回饋錯誤訊息
```json
"scripts": {
    "start:dev": "NODE_ENV=dev nodemon ./bin/www",
    "start:production": "NODE_ENV=production nodemon ./bin/www"
},
```
若是 windows 系統可能會遇到不支援執行以上指令的情況，可安裝 [cross-env 套件](https://www.npmjs.com/package/cross-env)
並調整為以下指令
```json
"scripts": {
    "start:dev": "cross-env NODE_ENV=dev nodemon ./bin/www",
    "start:production": "cross-env NODE_ENV=production nodemon ./bin/www"
},
```



<!-- ### 參考資源 -->

[GitHub 範例](https://github.com/gonsakon/express-week4-sample/blob/week5/app.js#L47-L86)

### 題目（將答案寫在 GitHub 並提交至回報區）
參考上方 error handler 範例，設計 POST 新增貼文時的 development 及 production 模式的錯誤處理，並以 POSTMAN 測試可正確運作

情境：
- request body 的 JSON 資料格式錯誤（缺少 `}`）
```json
// production 模式
{
    "status": 400,
    "message": "資料格式錯誤"
}

// devlopment 模式
{
    "status": 400,
    "message": "Unexpected end of JSON input",
    "error": {
        "expose": true,
        "statusCode": 400,
        "status": 400,
        "body": "{\n \"name\": \"test1\",\n \"content\": \"test1\",\n \"tags\": [\"感情\"],\n \"type\": \"person\"\n",
        "type": "entity.parse.failed"
    },
    "stack": "SyntaxError: Unexpected end of JSON input\n    at JSON.parse (<anonymous>)\n    ...略"
}
```
也可以其他錯誤情境練習，有正確回饋 development 及 production 模式的錯誤就 ok



## 回報流程

將答案連結貼至底下回報就算完成了喔! 
解答位置請參考下圖（需打開程式碼的部分觀看）

![](https://i.imgur.com/vftL5i0.png)

<!-- 解答：  

error handler 範例參考（也可自行依需求設計）

```javascript
const errorHandler = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';
  if (process.env.NODE_ENV === 'dev') {
    resErrorDev(err, res);
  } else if (process.env.NODE_ENV === 'prod') {
    if (err.isAxiosError == true){
      err.message = "axios 連線錯誤";
      err.isOperational = true;
      return resErrorProd(err, res)
    } else if (err.name === 'ValidationError'){
      // mongoose 資料辨識錯誤
      err.isOperational = true;
      return resErrorProd(err, res)
    } else if (err.name === 'SyntaxError') {
      err.statusCode = 400
      err.isOperational = true;
      err.message = '資料格式錯誤';
    } 
    resErrorProd(err, res)
  }
}
```

-->



回報區
---

| 報數 |       組別／Discord 名字       |                            Codepen／HackMD／其他回饋                            |
|:----:|:-----------------------:|:-------------------------------------------------------------------------:|
| 1 | 中 4 組 / jimkk159 | [HackMD - Day 23](https://hackmd.io/FUKUO4afTKqWpUZfrI3X5Q) |
| 1 | 北 10 組 / Benson | [Github - Day 23](https://github.com/ioveasdkre/HexschoolOperation/tree/main/NodejsEnterpriseClass/day40-tasks/day23/app.ts) |
|  2  | 北 13 組 / Louisa  | [GitHub - Day 23](https://github.com/louisa0416/NodejsEnterpriseClass/blob/master/daily-task/day23/week5-middleware/service/errorHandler.js) |
|  4  | 北 16 組 / 文文  | [GitHub - Day 23](https://github.com/chiawen81/nodeJS_DailyTasks_d20/tree/60c8439a66efdae42901d6601e86f87fbe23ff1c) |

