MIXXIN Vibe Coder 入門課
ADDENDUM · 第 4 堂盤點後補充

抽屜的另一半:拿東西有防護,放東西沒有

第 4 堂的作業全班交得很好——三件事幾乎每個人都做到了。但盤點的時候發現一件很整齊的事:14 份作業裡有 10 份,在同一個地方漏掉同一件事,而且漏的方式一模一樣。這不是你們誰粗心,是 AI 寫這種程式時的固定習慣。這一頁把它講清楚,最後有一個要交的小作業。

補課 · 非正課 14 份裡 10 份中招 看得懂 AI 的盲點 附特別指派作業
這一頁的完成定義
你能用自己的話說出「把東西放進抽屜這個動作,也可能會失敗」;並且你的頁面在三個存資料的地方(跟團狀態、天氣、全班清單)都有防護,就算抽屜被鎖住,畫面也不會壞掉、也不會騙你說存好了。

第 4 堂的作業是三件事:跟團狀態留得住、抓台北天氣、接上全班共用清單。盤點結果——14 份作業裡 12 份三件事全做到,這在入門第 4 堂算相當好。

但同時也發現,10 份作業在同一個位置漏掉同一件事。當同一個錯誤出現在 10 個人身上,它就不是誰的疏忽,而是你們共同的助手(AI)有一個固定盲點。認出這種盲點,比修好這一個 bug 重要得多——這是「會用 AI 寫程式」和「被 AI 寫的程式坑」的分界線。

三件事全做到12 人 / 14 人交件
寫入沒有防護(這頁要修的)10 人
寫入有防護4 人:Jamie、Lettice、woola、Tina
還有項目要補做3 人:Tina、Sandy、Sally(見最後一段)
01現象:畫面說「已跟團」,抽屜裡什麼都沒有

先講你會看到什麼。想像有位同事用無痕視窗(或把瀏覽器隱私設定調得比較嚴)打開你的頁面:

他按下「我要跟」畫面正常:人數 +1、按鈕變成「已跟團 ✓」
他重新整理全部歸零。人數退回去、按鈕變回「我要跟」
他跟你說「你的頁面壞了」你自己打開試——完全正常,怎麼試都對
這是最難抓的一種 bug:它只在別人的環境發生,你自己怎麼點都是對的。而且畫面從來沒有報錯——它只是安靜地沒有存進去,然後理直氣壯地顯示「已跟團」。

回到第 4 堂的比喻:localStorage 是瀏覽器裡的抽屜。你們都做對了「從抽屜拿東西」這件事——而且都想到了「抽屜可能是空的」(第一次打開頁面時裡面什麼都沒有),所以拿的時候都加了防護。

漏掉的是另一半:把東西放進抽屜,也可能失敗。有些情況下這個抽屜是鎖住的——無痕模式、瀏覽器的隱私設定、或抽屜已經塞滿。這時候「放進去」這個動作會出錯,而如果沒有防護,程式就停在那一行,後面該做的事全部不會發生。

02為什麼 AI 只防了一半
💡看穿它的思路

AI 在寫「拿」的時候,很容易想到「萬一抽屜是空的呢」——因為那是第一次打開頁面就會遇到的正常情況,它一定得處理。但寫「放」的時候,它預設放東西不會失敗——畢竟在它練習過的絕大多數情況裡,確實不會。

所以你拿到的程式碼會長成這樣:讀取那一段包著防護、寫入那一段光溜溜的。這種「一邊有一邊沒有」的不對稱,是你以後檢查 AI 產出時很好用的一個著眼點——不只是 localStorage,任何「有讀有寫」「有開有關」「有進有出」的成對動作,都值得問一句:另一半呢?

旁註(行話):這個「防護」在程式裡叫 try/catch——意思是「試著做這件事,萬一出錯就走另一條路,不要整個停掉」。你不需要會自己寫,但知道這個詞,你就能直接叫 AI 幫你補上。

還有一個更根本的問題:存不進去的時候,畫面卻說存好了。與其讓使用者以為自己跟團成功、隔天中午發現沒被算進去,不如老實告訴他「這台裝置記不住,重整後會不見」。這叫「誠實的失敗」,比「安靜的失敗」好一百倍。

03更歪的一種:明明抓到了,卻說「載入失敗」

有兩份作業(Sybil、sam)的情況再進一步:他們把「存進抽屜」和「去外面抓資料」這兩件事包在同一層防護裡。結果是——

去抓天氣✓ 成功,資料已經拿回來了
存進抽屜✗ 失敗(抽屜鎖住)
畫面顯示「資料載入失敗」——但它明明載入成功了

這種錯誤會讓你抓錯方向:畫面說載入失敗,你就跑去查網路、查網址、懷疑天氣服務掛了,怎麼查都查不出問題——因為真正壞掉的是後面那個「存」的動作。

觀念:兩件不同的事,要有各自的防護,也要有各自的說法。「抓不到資料」和「抓到了但記不住」是完全不同的兩件事,畫面上不該講同一句話。
04寫對的人:直接去看他們怎麼做

這件事最好的教材不在我這裡,在你同學的頁面上。這四位的寫入都有防護,寫法各有特色,建議直接打開來看:

Jamie三件事全對、審查完全沒挑出問題。跟團人數用「原本的數字 + 我加了幾個」的算法,重複整理畫面也不會算歪
Lettice三件事全對、審查完全沒挑出問題。抽到沒有評分的店家時,兩種情況(沒有這個欄位、欄位是空的)都擋掉了,不會跑出奇怪的星星
woola把「抓資料 → 存抽屜 → 失敗就退回上次存的」抽成同一套流程給三個資料共用,連不上時畫面標「離線・上次抓取」而不是壞版
Tina共用清單那項還沒做,但她已經做的兩處寫入都有防護,而且抓不到天氣時會退回顯示上次的資料並標「(快取)」——誠實的失敗就是這個意思
去看同學的作品:作業索引點進他們的個人頁,可以直接開啟頁面、也能看到當初的 PR。看別人怎麼解同一題,是這堂課最便宜的進步方式。
·特別指派作業

全班都要做(包含上面三位寫對的人——你們的任務是順手幫其他人看)。一張 issue + 一個 PR,照舊。

第 1 件 · 把抽屜的另一半補上

  • 找出你頁面裡所有「存進 localStorage」的地方(跟團狀態、天氣、全班清單,通常三處)
  • 每一處都要有防護:存不進去時,畫面不能壞掉、也不能騙人說存好了
  • 「抓不到資料」和「抓到了但存不住」要顯示不同的訊息
  • 自己驗一次:開一個無痕視窗打開你的頁面,按「我要跟」再重整——畫面不能壞掉

起手式 · 用自己的話改

A把三個寫入點都補上防護
我的頁面有三個地方會把資料存進 localStorage:跟團狀態、天氣、全班共用清單。
請幫我檢查這三個地方,把「寫入」也包上 try/catch(我現在只有「讀取」有包)。
另外請把「抓資料失敗」和「抓到了但存不進 localStorage」分成兩種情況處理:
存不進去的時候,畫面要照常顯示抓回來的資料,但要誠實告訴使用者
「這台裝置記不住,重新整理後會不見」,不要顯示成「載入失敗」。
B自己驗一次(無痕模式)
請告訴我怎麼用無痕視窗測試我的頁面在「localStorage 不能寫入」時的行為,
以及我應該在開發者工具的哪個面板、看到什麼,才算確認防護真的有效。

第 2 件 · 把 PR 描述那三個問題答完

第 4 堂要求 PR 描述回答三個問題,盤點結果:14 份全部沒答完——「換裝置會不會不見」一個人都沒寫到。這題不是形式,它就是第 6 堂的入口:如果資料只活在你這台電腦的抽屜裡,那「同事看得到你跟團」這件事永遠做不到。

  • 這個資料存在哪裡?(存在哪個抽屜、用什麼名字)
  • 重整會不會不見?換裝置會不會不見?(兩個都要答,換裝置那題是重點)
  • 我加的 fetch 資料來源需不需要密碼?(天氣和全班清單兩個都要答)

個別補做(只有這三位)

Tina共用清單那項還沒做——你目前的清單是第 2 堂「抄」進來的固定清單,頁面上寫的「22 家店」現在實際已經是 35 家。改成 fetch 就會自動跟上
Sandy共用清單有去抓、但抓回來的資料沒有接到畫面上——你顯示的總數和隨機推薦還是從自己那份固定清單來的。這個「有抓但沒接上」很難自己發現,值得看一次是怎麼回事
Sally第 4 堂還沒交。三件事的起手式在第 4 堂頁面上都有,照著做就好;卡住隨時找我

講師 / 助教檢核重點

  • 三個寫入點都有防護,無痕視窗實測畫面不壞、不假報成功
  • 「抓不到」與「存不住」顯示不同訊息
  • PR 描述三問答完,特別是「換裝置會不會不見」
  • 學員能用自己的話說出「AI 只防一半」這個盲點