iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
自我挑戰組

SPYxFRONTEND ~ 懂一點後端真是讓人哇哭哇哭系列 第 26

[Day26] 前端查案系列(1)~來找出真正的兇手吧!‧ 無法新增資料事件 (通靈程度:★)

  • 分享至 

  • xImage
  •  

前言

為了模擬一些前端可能遇到的 issue,
我試著在 API 寫了一點手腳,
但我先不說我在 API 寫了什麼,
就跟著我的腳步一起來看看到底發生什麼問題,
最後又發現是誰的問題呢?

這邊先前情提要一下檔案架構:
https://ithelp.ithome.com.tw/upload/images/20220927/20129873y4EZ55qeQu.png
紅框處就是我們今天比較會接觸到的檔案~
(PS. 這個架構應該沒有很正確,但就是測試用,所以就請不要太介意XD)

開始前也先記得打開前後端:
後端:node server.js
前端:npm start

本日正文

故事:無法新增資料

今天鐵人餐廳的員工小鐵一如既往的在餐廳打烊後要在後台 key 今日的銷售數量,
正常輸入完品項跟數量後卻出現以下問題:

出現錯誤訊息,而且只說是 未知的錯誤
於是小鐵報案給工程師,
因為這是系統畫面出的錯誤,
所以前端工程師小前會先收到這個報案。

查案流程

小前第一步就先看看後端有沒有問題,
看起來查詢資料沒有問題,
於是接著小前模擬小鐵的動作,
發現也會出現一樣的錯誤訊息。
https://ithelp.ithome.com.tw/upload/images/20220927/20129873bzddII10Ul.png

「那輸入其它的值看看會不會有問題吧!」

於是小前把 臭豆腐 改成 香豆腐 再試一次:
https://ithelp.ithome.com.tw/upload/images/20220927/20129873O9oJQoZRxj.png

小前發現他改成 香豆腐 call API 就成功了,
那再輸入一次 香豆腐 呢?
https://ithelp.ithome.com.tw/upload/images/20220927/20129873jr1I1472Gb.png

哦?這次也遇到一樣的錯誤了,
於是他決定在 app.js (前端的 code) 埋一下 console.log 來看 API 回了什麼。

 .catch(function (e) {
      console.log(e); // 多了這行
      let err;
      switch(e?.response?.status) {
				case 403:
					err = '您沒有新增的權限,請確認後再試。';
					break;
				default:
					err = '未知的錯誤';
			}
      ... (略)
    });

https://ithelp.ithome.com.tw/upload/images/20220927/20129873NwPPvAzBig.png

他發現 API 回了 409
可是沒有更詳細的資訊,
他還是不知其所以然,
難道要來通靈了嗎

還是直接報案給後端?
不,等等,小前發現他知道 API 的 code 在哪裡,
於是小前決定打開 server.js 一探究竟。

第一步打開 server.js
直接搜尋 409 看看吧!
https://ithelp.ithome.com.tw/upload/images/20220927/20129873XZNrDmpCGC.png

果不其然馬上找到關鍵處,
就是這段:

server.use((req, res, next) => {
  if (req.method === 'POST') {
    const sales = readSales();
    const sale = sales.filter(s => s.item === req.body.item)[0];
    if (sale === undefined || sale === null) {
      next();
    } else {
      res.sendStatus(409);
    }
  } else {
    next()
  }
 })

首先會去判斷 sale === undefined || sale === null
不是的話才會執行 res.sendStatus(409)
sale 又是什麼?
往上一行追:

const sale = sales.filter(s => s.item === req.body.item)[0];

是從 sales.filter 而來,
sales 又是什麼呢?
再繼續往上追:

const sales = readSales();

readSales 又是啥咪?
搜尋一下 readSales 可以找到這段:
https://ithelp.ithome.com.tw/upload/images/20220927/201298735WMOyV1GOg.png

function readSales() {
  const dbRaw = fs.readFileSync('./db.json');  
  const sales = JSON.parse(dbRaw).sales;
  return sales;
}

看起來是去找 db.json 裡面的 sales 存起來成 sales
那我們再回去看這兩行:

const sales = readSales();
const sale = sales.filter(s => s.item === req.body.item)[0];

所以這兩行意思就是,
比對 db.jsonsales 的資料,
一筆一筆去跟 req.body 去比對 item,
(PS. req 就是指 request,也就是前端發給 API 的要求,
所以 req.body 就是指 request 的內容。)

const sales = readSales();
    const sale = sales.filter(s => s.item === req.body.item)[0];
    if (sale === undefined || sale === null) {
      next();
    } else {
      res.sendStatus(409);
    }

這幾行再一起看,sales 比對不到就會繼續做,
比對到已經存在就要拋出 409 的 HTTP 狀態碼。

哦!事情到這裡已經明朗了,
也就是說 臭豆腐 這筆資料已經存在了是嗎?
讓我們來檢查看看:
http://localhost:10000/sales
https://ithelp.ithome.com.tw/upload/images/20220927/20129873MTk16ByFho.png

BINGO!臭豆腐 已經存在所以無法成功新增,
小前就可以開心結案了...

不不不,
還差一步,
還記得之前的文章前端的 code 只有處理 403 的 HTTP 狀態碼嗎?

switch(e?.response?.status) {
				case 403:
					err = '您沒有新增的權限,請確認後再試。';
					break;
				default:
					err = '未知的錯誤';
			}

所以除了 403 以外的錯誤都會顯示 未知的錯誤
這也是導致使用者小鐵不知道發生什麼事只能報案給工程師的主因,
這時候小前就要把 409 的情況也加進來,
像這樣:

switch(e?.response?.status) {
    case 403:
        err = '您沒有新增的權限,請確認後再試。';
        break;
    case 409:
        err = '此項目已存在,請確認輸入的資料是否有誤。';
        break;
    default:
        err = '未知的錯誤';
    }

然後也同步來確認看看錯誤訊息有沒有成功顯示吧!

沒錯,事情到這裡就算圓滿結束了,
小前可以跟小鐵說是因為資料已經存在,
而下次如果再輸入相同的資料,
就會顯示 此項目已存在
小鐵就會知道是自己輸入了重複的資料,
從此小鐵再也不會報案了,
小前從此過著幸福快樂的日子...

... 最好是啦!

(To Be Continued...)

整理查案流程

  1. 跟使用者做同樣的動作(輸入資料)看看
  2. 試著輸入不同值看看
  3. console.log 看 API 有沒有詳細訊息
  4. 稍微簡單搜尋 API 的 code 看看有沒有可疑的蛛絲馬跡
    (PS. 前端在看 API 的 code 只要看個大概,
    不用每一行都要弄得很懂,畢竟我們不是專業的後端orz)
    (5.如果4再不行可能真的得跟後端報案了orz)

每日一字:409 Conflict

409 Conflict

HTTP 409 Conflict 表示請求與伺服器目前狀態衝突

衝突通常發生於 PUT (en-US) 請求。如上傳一個已經有舊版本存在於伺服器的檔案而導致版本控制衝突時,會回復一個 409 錯誤。

Conflict 字面上來看其實就是衝突的意思,
所以我們看到 409 就大概會可以先猜是因為資料重複或其它狀況導致的衝突問題。

參考文章

4 - Add JSON server
=> 感謝大大詳細文章orz 因為老實說 JSON Server 的官方文件不算寫得很詳細XD
(我猜可能是要給本來就是在寫 API 的開發者看的吧orz)

後記

這幾天文章終於來到有趣的報案系列XD
不過說實話,後端在寫 API 時就會把出錯的各種情況寫好,
提醒前端要在前端頁面加上這些錯誤訊息提醒視窗,
但我初期在寫前端時,
因為不知道這些眉角,
所以也算是因為這樣多學怎麼看後端的 code。
然後因為要自己模擬 API 錯誤,
網路有提供 call 的 API 又沒辦法這麼客製化,
所以只好自己捲起袖子寫 API 了XD
不過我寫的都很簡單啦orz
我知道離真正的後端還有很長一段路orz


上一篇
[Day25] 走到 router 才拋 HTTP 狀態碼是沒用的~ 為什麼前端需要知道 API 怎麼丟 HTTP 狀態碼?
下一篇
[Day27] 前端查案系列(2)~來找出真正的兇手吧!‧ 資料顯示異常事件 (通靈程度:★★)
系列文
SPYxFRONTEND ~ 懂一點後端真是讓人哇哭哇哭30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言