--- tags: Node.js 直播班 - 2022 春季班 --- # 第五週主線任務與講義 * 錄影 * 週日早上 10 點,加碼 JWT 第六週 * 點名,[報到]() Code:`L2VVbpYId0Bl` * 每日助教服務上線! * [線上講義](https://whimsical.com/NJzhqQpRX1YcogzPz6ro5e) * [線上範例程式碼](https://github.com/gonsakon/express-week4-sample) ## express middleware * [middleware 中介介紹](https://expressjs.com/zh-tw/guide/using-middleware.html) ### app.use ``` =JavaScript const express = require('express'); const app = express(); app.get('/',function(req,res){ res.status(200).json({ "status":"success", "message":"你目前造訪到首頁" }) }) app.use(function(req,res,next){ console.log('有人進來了'); kk(); next(); }) app.use(function(req,res,next){ res.status(404).json({ status:"false", message:"您的路由不存在" }) }) app.use(function(err,req,res,next){ console.log(err.name); res.status(500).json({ "err": err.name }) }) // 監聽 port var port = process.env.PORT || 3000; app.listen(port); ``` ### error 處理 * [官網資訊](https://expressjs.com/zh-tw/guide/error-handling.html) ```=JavaScript const express = require('express'); const app = express(); app.get('/',function(req,res){ res.status(200).json({ "status":"success", "message":"你目前造訪到首頁" }) }) app.use(function(req,res,next){ console.log('有人進來了'); next(); }) app.get('/user',function(req,res){ res.status(200).json({ "status":"success", "message":"你目前造訪到 user 頁面" }) }) app.use(function(req,res,next){ res.status(404).json({ status:"false", message:"您的路由不存在" }) }) app.use(function(err,req,res,next){ console.log(err.name); res.status(500).json({ "err": err.name }) }) // 監聽 port const port = process.env.PORT || 3003; app.listen(port); ``` ## 中介設計 ```=javascript const express = require('express'); const app = express(); const checkKeyword = function(req,res,next){ if(req.query.q){ next() }else{ res.status(400).json({ "message":`您並未輸入關鍵字` }) } } app.get('/search',checkKeyword,function(req,res){ res.status(200).json({ "status":"success", "keyword":`你搜尋到的是${req.query.q}` }) }) // 監聽 port const port = process.env.PORT || 3003; app.listen(port); ``` ## 中場休息 - 分享之後帶專題流程 <!-- 每週日晚上 21:00~10:30 帶各組專題, //依照第三週組別來分享:https://hackmd.io/Rre5Zu9-QTyFQyqxQv8qwg // 最晚 5/15 當天討論時,確認是否要參加 // 5/15 各組請分享 // 1. 各組員分工,前端 ng、Vue、React // 2. 分享要做哪些額外功能,目前研究狀況 // 3. 目前分工到哪裡?先出一個簡易 API 時程甘特圖 // https://docs.google.com/spreadsheets/d/1TukAvPNVHgENAUqqJdV9YBW992S4OfqI2ICa0xVRmxo/edit#gid=0 ### 預期工時(會請 Ray 看,並請他監控各組品質) 1. 5/14 完成前後端切版、不能再改需求 2. 5/14 前確認 API 支數,不能再變更 API 支數 3. 5/21 要完成前後端 登入註冊、修改會員資料 API 4. 5/22~6/4:進入高速開發期 5. 6/4 完成度需達 85% 6. 6/4~6/12 修 BUG,準備簡報 --> - 小組任務講解 - 下週將公布獎品 ## 下半場 1. 404、express 全域錯誤補捉設定 2. 補捉程式錯誤、catch 補捉 3. 自訂可預期錯誤 appError 4. 增加開發狀態與上線狀態的錯誤回饋 5. 增加統一處理 asyncError 服務 ## error 處理 * [JS error 介紹](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error) * try catch 示範 ``` JavaScript const a = new Error("姓名欄位沒有填寫") a.name = "驗證失敗" ``` ## 補捉程式錯誤 ```=javascript process.on('uncaughtException', err => { // 記錄錯誤下來,等到服務都處理完後,停掉該 process console.error('Uncaughted Exception!') console.error(err); process.exit(1); }); ``` ## 補捉未處理的 catch ``` =JavaScript // 未捕捉到的 catch process.on('unhandledRejection', (reason, promise) => { console.error('未捕捉到的 rejection:', promise, '原因:', reason); // 記錄於 log 上 }); ``` ## async 補充 * [MDN 補充](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/async_function) ``` =JavaScript async function add(a) { const data = await a+a; return data; } add(3) .then(res=>console.log(res)) .catch(err=>console.log(`error!! ${err}`)) ``` ## 重構自訂 try catch(util/handleErrorAsync.js) ``` =JavaScript const handleErrorAsync = function handleErrorAsync(func) { // func 先將 async fun 帶入參數儲存 // middleware 先接住 router 資料 return function (req, res, next) { //再執行函式,並增加 catch 條件去捕捉 // async 本身就是 promise,所以可用 catch 去捕捉 func(req, res, next).catch( function (error) { return next(error); } ); }; }; module.exports = handleErrorAsync; ``` ## 額外補充 在 Window 上面設定 development 與 production 時會有一些狀況發生 ```json "start:dev": "NODE_ENV=dev nodemon ./bin/www" ``` 因此若要讓環境變數正確運作的話,要額外安裝 [cross-env](https://www.npmjs.com/package/cross-env) 套件,並改為以下寫法才能順利執行 ```json "start:dev": "cross-env NODE_ENV=dev nodemon ./bin/www" ``` ## 第五週主線任務 * [第五週主線任務網址]()