iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
JavaScript

從看不懂到做出來,用 PawPal 走過前端新手村系列 第 15

Day 15|Debug 到懷疑人生的那一天

  • 分享至 

  • xImage
  •  

今天的故事

開發 PawPal 時,我遇過不少會直接跳出紅色錯誤訊息的問題。

但這次不一樣。

當時 Dashboard 上的寵物名稱和照片都正常,只有年齡顯示成 -

畫面沒有壞掉,Console 也沒有直接告訴我答案。

我不知道問題是在元件、API,還是日期格式,只能從眼前的結果一步一步往回查。


原本可以顯示,為什麼串接 API 後不行?

在還沒串接真實 API 時,前端使用的 mock data 本來就已經有可以直接顯示的年齡資料。

概念上就像:

const pet = {
  name: '阿黑',
  age: '2歲',
}

畫面只需要讀取:

pet.age

就能把年齡顯示出來。

但後來改成串接真實 API,資料來源變了。

後端並沒有直接幫前端算好 age,而是提供寵物的:

birthday

概念上就像:

const pet = {
  name: '阿黑',
  birthday: '2024-05-10',
}

當時的 PetCard 還在讀:

pet.age

所以串上真實資料後,這個值變成空的,最後畫面就顯示原本設定的 fallback:

-

這也是這次 Bug 真正有趣的地方。

API 其實有正常回傳資料。

寵物名稱和照片也都存在。

只有年齡的資料來源改變了,但前端顯示方式還沒有一起調整。

剛開始看到畫面時,我當然還不知道問題就在這裡。


沒有方向時,我先用了 console.log()

因為畫面沒有提供足夠的線索,我當時先用 console.log() 把取得的寵物資料印出來。

console.log(pet)

這個動作看起來很簡單,但對當時的我來說很重要。

因為在沒有方向的情況下,我至少可以先確認:

API 到底有沒有回傳資料?
→ 回傳了哪些欄位?
→ 年齡相關資料叫什麼名字?
→ 欄位裡實際放了什麼內容?

把資料攤開來看之後,我才慢慢發現:

不是 API 完全沒有回傳資料,而是前端想讀取的欄位,和 API 實際提供的欄位不一樣。

原本畫面期待的是:

pet.age

但真實資料提供的是:

pet.birthday

到這裡,問題的範圍一下就小很多。

它不是整支 API 壞掉。

也不是整張寵物卡片失效。

真正需要處理的是:

既然後端給我的是生日,那前端要怎麼把生日轉成年齡?

從這次開始,我才真正理解,console.log() 不只是把資料印出來。

它也可以幫助我確認現在到底拿到了什麼,然後一步一步排除不相關的可能性。


找到欄位問題後,又卡在日期

確認 API 提供的是 birthday 後,下一步很自然:

那就用生日算年齡。

聽起來很簡單。

但真的開始寫時,我又遇到新的問題。

生日從 API 回來時是一段日期資料,我需要先確定:

生日有沒有值
→ 日期能不能正常解析
→ 目前日期和生日差多少
→ 最後要怎麼顯示成年齡

專案原本就已經有處理寵物生日顯示的共用函式 formatPetBirthday()

它會處理像:

YYYY-MM-DD

以及 API 常見的 ISO 日期時間格式,再整理成畫面需要的生日顯示格式。

處理這次年齡 Bug 時,我又加入了:

formatPetAge(birthday)

讓寵物年齡可以直接由 birthday 計算。

最後畫面可以依照年齡顯示:

2歲3個月
8個月
未滿1個月

如果沒有生日、日期無法解析,或生日是在未來,則會回傳:

-

這裡我後來重新看 Repository 才發現一件事。

目前的 formatter 並不是完整的「日期合法性驗證器」。

像某些外觀看起來符合 YYYY-MM-DD、實際日期卻不存在的值,不一定都會被判定成錯誤。

所以更精準地說:

formatPetAge() 負責把專案目前可解析的生日資料轉成年齡顯示,並處理空值、無法解析的資料與未來生日。

而不是所有「不合理日期」都一定會被攔下來。


共用工具也是慢慢長出來的

重新看 Git 歷史後,我才發現這幾個函式其實不是同一次建立的。

專案先整理了:

formatPetBirthday()
formatPetGender()

把生日和性別的顯示邏輯集中到:

src/utils/petDisplay.js

後來遇到這次 Dashboard 年齡顯示的 Bug,才再把:

formatPetAge()

加入同一個共用 utility。

而修正後,PetCard 和 PetProfileModal 都可以使用同一套年齡顯示邏輯。

這讓我開始理解,共用函式不一定是一開始就規劃好全部需求。

有時候是專案慢慢開發、問題慢慢出現之後,才發現:

這個規則不應該散落在不同元件裡。

如果每個畫面都自己算一次年齡,之後只要顯示規則改變,就很容易出現不同地方顯示不同結果。

把它集中到共用工具後,元件只需要負責顯示結果。


畫面沒有報錯,也可能需要 Debug

以前我對 Debug 的想像比較像:

程式執行失敗
→ Console 出現紅色錯誤
→ 根據錯誤訊息修改

但這次不是。

API 有成功回應。

元件也有正常顯示。

寵物名稱和照片都看得到。

只有年齡變成:

-

這種問題不會直接跳出一句:

你的 age 和 birthday 沒有對上

只能自己把流程拆開來看。

畫面現在顯示什麼?
→ 元件正在讀哪個欄位?
→ 實際拿到的資料有哪些欄位?
→ Mock data 和 API Response 有什麼不同?
→ birthday 要經過什麼轉換才能顯示成年齡?

確認完這些地方後,問題才慢慢縮小。

最後真正的原因其實很單純:

Mock data
→ 有 age

真實 API
→ 有 birthday,沒有 age

舊 PetCard
→ 還在讀 pet.age

把修正前後放在一起看,就更清楚。

修正前

PetCard
→ 直接讀取 pet.age
→ API 沒有 age
→ 顯示 -

找到問題後,改成:

修正後

PetCard
→ 使用 pet.birthday
→ formatPetAge(pet.birthday)
→ 顯示實際年齡

這次我才真正感受到,Debug 不一定是在找一段「寫錯的程式碼」。

有時候每一段程式各自看起來都沒有壞掉,真正出問題的是:

資料來源已經改變,但使用資料的地方還停留在原本的寫法。

也因為這樣,我後來在串接 API 時,會更注意前端原本使用的資料結構,和真實 API Response 到底是不是一樣。

所以真正需要修的不是 API。

而是前端要跟著真實資料結構一起調整。


解決問題後的成就感

當年齡終於正常顯示時,我其實很有成就感。

不是因為這是一個多複雜的功能。

而是這次沒有一個錯誤訊息直接告訴我:

問題就在這裡。

我是從畫面上的一個 - 開始,慢慢往回確認:

畫面
→ 元件
→ 資料
→ 欄位
→ 日期
→ 年齡顯示

最後才找到真正的原因。

這也讓我開始改變遇到 Bug 時的反應。

以前看到畫面不對,我可能會先懷疑版面,或直接進入元件裡不斷修改。

但後來我會先問:

畫面現在拿到的資料,到底長什麼樣子?

因為畫面只是最後看到的結果。

真正的問題,很可能早就在資料取得、欄位對應或格式轉換的過程中發生了。


如果現在重新 Debug 一次

如果現在再遇到同樣的問題,我會先做三件事:

確認畫面正在讀哪個欄位
→ 看實際取得的資料
→ 比對 API Response 和前端使用方式

例如這次:

畫面讀 pet.age

接著確認資料:

API 有 birthday
但沒有 age

那問題就已經縮小到:

birthday
→ age display

接下來才去處理日期轉換和年齡計算。

這樣比一開始就在元件裡到處修改,更容易知道自己現在到底在排查哪一層。


本篇重點與學習心得

這次可以先記住幾件事:

  1. 畫面沒有報錯,不代表顯示結果就是正確的。
  2. Mock data 能正常使用,不代表串接真實 API 後可以直接沿用。
  3. API 有成功回傳,不代表前端讀取的欄位一定正確。
  4. console.log() 可以幫助確認目前真正拿到的資料。
  5. Debug 時可以從畫面、元件、資料與欄位一層一層縮小範圍。
  6. 共用 formatter 可以讓不同元件使用相同的資料顯示規則。

這次最重要的學習是:

Debug 的重點不是一直亂試,而是一次確認一個環節。

當我不知道答案時,不需要一開始就猜中 Bug 在哪裡。

可以先從目前確定的事情開始:

畫面顯示不正確
→ 確認畫面讀取的欄位
→ 確認實際取得的資料
→ 比對兩邊的差異
→ 再處理真正有問題的地方

每確認一個環節,就能排除一部分可能性。

Debug 還是會讓人懷疑人生。

但至少這次之後,我不再只是對著程式碼亂改。

而是開始知道:

不知道問題在哪裡的時候,就先想辦法把問題範圍縮小。


下一篇預告

下一篇,我想從手機版選取醫院卡片的情境出發。

功能其實已經有反應,但畫面還停在列表裡,使用者看不到地圖上的選取結果。

功能成功,真的就代表使用者感受得到嗎?

Day 16,我會繼續整理這次手機版操作上的問題,以及我開始理解的 UX 差異。

下一篇:

Day 16|功能明明有反應,為什麼手機用起來還是不順?


上一篇
Day 14|權限控管:不是每個人都能做每件事。
下一篇
Day 16|功能明明有反應,為什麼手機用起來還是不順?
系列文
從看不懂到做出來,用 PawPal 走過前端新手村20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言