第 4 週 · 關聯、登入與佈署
Pages Functions、錯誤處理、logs
認識 Pages Functions 的檔案路由,並學會對客人隱藏內部錯誤、對自己留下紀錄。
正在打開這一關…
學習目標
- 說明 Pages Functions 如何用檔案路徑變成 API
- 寫出對客人友善、對自己有用的錯誤處理
- 打開 Workers 的 logs 與 traces
這門課的網站本身是靜態的 Cloudflare Pages:建置出 dist,沒有自己的 API。留言板則需要 API。你有兩條常見的路:
- Pages Functions:在 Pages 專案的
functions/放檔案,路徑就變成 API。適合「靜態站旁邊加幾個端點」。 - Worker 加上靜態資源:一支程式同時負責 API 與頁面。期末留言板用這條,因為 D1、KV、R2 與頁面在同一個專案比較好說明。
兩條都要會看懂。平台目前也提供把既有 Functions 編成 Worker 的路,新的完整產品更常直接寫 Worker。
用生活例子理解
Pages Functions 像靜態展場旁邊的服務台。檔案放在 functions/api/hello.js,網址就是 /api/hello。onRequestGet 只接 GET,onRequestPost 只接 POST。
生活比喻:錯誤處理是櫃台的兩種聲音。對客人說「現在無法完成」,對辦公室的紀錄本寫下路徑與錯誤種類。不要把倉庫地圖交給客人,也不要在紀錄本空白。
紀錄用結構化的 JSON,console.error 表示這則比較嚴重。設定檔要同時打開 observability.enabled 與 observability.traces.enabled。只開外層不會自動開啟追蹤。
本機看輸出就在跑 wrangler dev 的那個終端機。線上可以在儀表板看 Workers Logs,或用 npx wrangler tail 串流近期紀錄。
動手做
大約 25 分鐘。
- 讀案例的
functions/api/hello.js,說出網址會是什麼。 - 在期末範例的 Worker 設定加上
observability區塊。 - 故意在本機請求一個會失敗的路徑,或暫時寫
throw new Error("練習用錯誤"),看終端機有沒有你的 JSON 紀錄。看完立刻刪掉這行。 - 確認回應給瀏覽器的是通用句子,沒有
練習用錯誤這幾個字。 - 寫下三個你不會記進 log 的東西:密碼、胡椒、完整的 cookie。
案例
export function onRequestGet() {
return Response.json({ ok: true, message: "哈囉,這是 Pages Function" });
}動態路徑用資料夾與中括號。functions/api/messages/[id].js 對應 /api/messages/123,編號在 context.params.id。
export function onRequestGet(context) {
return Response.json({ id: context.params.id });
}Worker 的錯誤外殼:
export default {
async fetch(request, env) {
const url = new URL(request.url);
try {
return await handle(request, env, url);
} catch (error) {
console.error(JSON.stringify({
level: "error",
path: url.pathname,
message: error instanceof Error ? error.message : "unknown",
}));
return Response.json({ error: "伺服器暫時無法完成這件事" }, { status: 500 });
}
},
};{
"observability": {
"enabled": true,
"traces": {
"enabled": true
}
}
}流量大時再把 head_sampling_rate 調低。留言板這種作業先全收即可。
常見錯誤
- 把堆疊直接
return new Response(String(error))。客人不需要,攻擊者卻可能因此認識你的結構。 - 只
console.log("失敗"),沒有路徑。十筆失敗時你不知道是哪扇門。 - 以為開了
observability.enabled就有追蹤。追蹤要另外traces.enabled。 - 在 Pages 專案找
export default { fetch },或在 Worker 找onRequest。兩套入口不要混用。Functions 是onRequest/onRequestGet。Worker 是預設匯出的fetch。
自我檢查
functions/api/hello.js對應哪個網址?- 客人看到的錯誤句子,和你留下的紀錄,為什麼要不同?
- 期末留言板為什麼用 Worker 加靜態資源,而這門課網站用 Pages?