昨天把 fetch() 改成 async / await 之後,
整體終於看起來比較像正常人會寫的東西。
本來想說:
好,今天應該可以和平一點了吧。
結果我故意把 API 網址改錯。
重新整理。
畫面:
……
安靜。
非常安靜。
不是欸!資料沒拿到,你至少跟我講一聲吧???
所以今天來看一下:
API 出錯的時候,到底要怎麼處理。
昨天大概是這樣:
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
const data = await response.json();
console.log(data);
} catch (error) {
console.log("出事了!", error);
}
}
getUser();
看起來已經有:
try...catch
感覺很安全。
結果如果我把網址改成:
https://jsonplaceholder.typicode.com/users/999999
有些情況下 fetch() 還是會成功拿到 Response。
只是回來的狀態不是我們期待的成功結果。
我:
蛤?失敗了還算成功???
JavaScript:
我只負責送到,對方回你什麼是另一回事。
好喔 ==
這時候可以檢查:
response.ok
例如:
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
if (!response.ok) {
throw new Error("資料取得失敗");
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error.message);
}
}
這樣如果 Response 不是成功狀態,
就可以自己丟出錯誤:
throw new Error("資料取得失敗");
然後讓 catch 接住。
終於。
這次有人出事會記得通報了。
Response 裡還可以看到:
response.status
例如:
console.log(response.status);
常見的狀態像:
200 → 成功
404 → 找不到
500 → 伺服器出事
看到這裡突然覺得 API 很像客服系統。
不是直接跟你說:
「成功。」
就是:
「找不到。」
再不然就是:
「我們這邊系統有點問題,請稍後再試。」
很熟悉的感覺 XD
如果今天真的做網頁,
總不能 API 掛掉之後只在 Console 裡:
console.log("出事了!");
使用者根本看不到啊。
所以可以直接把錯誤顯示在畫面上。
HTML:
<p id="message">資料載入中...</p>
JavaScript:
const message = document.querySelector("#message");
async function getUser() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/1"
);
if (!response.ok) {
throw new Error("資料取得失敗");
}
const data = await response.json();
message.textContent = data.name;
} catch (error) {
message.textContent = "資料讀取失敗,等等再試 QQ";
}
}
getUser();
成功就顯示資料。
失敗就顯示:
資料讀取失敗,等等再試 QQ
至少不會畫面一片空白,
然後讓使用者開始懷疑:
是網站壞了,還是我壞了???
既然 API 不是馬上回來,
那資料還沒到的時候,
最好也讓使用者知道:
我有在處理,不是當機。
所以一開始可以先顯示:
資料載入中...
等成功:
message.textContent = data.name;
失敗:
message.textContent = "資料讀取失敗";
這樣整個流程就比較完整:
載入中
↓
成功 → 顯示資料
↓
失敗 → 顯示錯誤訊息
response.ok
確認 Response 是否成功。
response.status
查看 HTTP 狀態碼。
throw new Error()
自己丟出錯誤。
try...catch
把錯誤接住。
所以今天的版本大概就是:
async function getData() {
try {
const response = await fetch("API網址");
if (!response.ok) {
throw new Error("資料取得失敗");
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error.message);
}
}
以前寫 API 最開心的情況就是:
成功有資料!
然後就收工了。
完全沒想過:
如果失敗呢?
結果今天才發現,
真正做網頁的時候,不可能永遠假設 API 都會乖乖回資料。
所以除了:
Happy Path
也要記得處理:
「事情不 Happy 的時候怎麼辦。」
至少 API 出事的時候,
不要所有人一起沉默。
畫面沉默。
Console 沉默。
我也沉默。
那真的太尷尬了 XD
好啦。
今天成功讓錯誤也有地方可以去。
Day 24,完成!