如果對方的 api 是壞掉的,怎麼處理異常狀態?

學生提問

  • 如果對方的 api 是壞掉的,怎麼處理異常狀態
  • 在網路上有看到 response.ok(是如果回應的狀態介於 200-299 之間,則會是 true),想請問這個可加可不加?

回答

首先先科普一下常見的 http 狀態碼

  • 200 成功
  • 400 參數錯誤
  • 404 找不到
  • 500 例外錯誤

這邊要特別注意: 狀態碼是看人寫的,有的團隊只會回傳 200 和 500,並不會出現 4xx!

前端建議都加上 response.ok 的判斷

因為 fetch 在後端錯誤時(狀態碼 5xx, 4xx )不會進入 try_catch 判斷

文章最後有附上驗證的程式碼

fetch 異常判斷程式碼可以這樣寫

// 範例使用方式:
// 到 https://randomuser.me 網站開檢查,把下方程式碼貼上
// 可以故意把網址打錯就能看到錯誤拋出

function getUsers() {
  return fetch("https://randomuser.me/api1/")
    .then((response) => {
      if (!response.ok) {
        //不是200開頭會將錯誤包裝起來,丟出
        const err = new Error(`HTTP status code: ${response.status}`);
        err.response = response;
        err.status = response.status;
        throw err;
      }
      return response;
    })
    .then((response) => response.json())
    .then((data) => {
      console.log(data);
      return data.results;
    });
}
async function main() {
  try {
    const response = await getUsers();
    console.log(response);
  } catch (error) {
    // 這邊負責處理出錯的邏輯
    console.log(error, error.status, error.response);
    // 關閉loading動畫 or 彈出提示 ...etc 看需求撰寫
  }
}
main();

驗證 fetch 遇到 404 不會進入 catch

// 範例使用方式:
// 到 https://randomuser.me 網站開檢查,把下方程式碼貼上

//故意打錯的網址
function getUsers() {
  return fetch("https://randomuser.me/apitesttest/")
    .then((response) => {
      console.log("雖然404但還是能正常印出,不會到 catch");
      return response;
    })
    .then((response) => {
      //這邊錯誤才會進入 catch
      return response.json();
    })
    .then((data) => {
      return data.results;
    })
    .catch((error) => {
      console.log(`Error: ${error}`);
    });
}
async function main() {
  const response = await getUsers();
  console.log(response);
}
main();

很好的進階閱讀教材

https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html

參考資料

https://stackoverflow.com/questions/40248231/how-to-handle-http-code-4xx-responses-in-fetch-api