iT邦幫忙

0

請問關於React Axios的Promise回傳處理問題?

如題,目前一個專案在處理Axios時我是用之前一個Youtube教的方式程式碼如下:

export const getOverview = async () => {
    let config = {
      headers: { 'token': token },
    }
    try{
      const response = await axios.get(BASE_URL + 'xxx/overview', config)
      if(response.data.code === 200) {
        return [response, null, null]
      } else {
        return [null, response.data.code, null]
      }
    } catch(error) {
      return [null, null, error]
    }
  }

原本Youtube上教的是在處理時依照成功與失敗只在try和catch回傳陣列
[response, null] 與 [null, error]
這樣在頁面調用這個Axios時就可以直接取得Promise的回傳的長[response, null] 或 [null, error]其中之一,以此來判斷抓取資料是否成功

但遇到一個問題是,我們後端有做錯誤碼資訊的回傳,所以我自己多加了一個陣列元素在try裡去判斷回傳的code是否200或是錯誤的403之類的,但發現調用時,有些情況會跑try裡面的code判定,有些情況會跑catch裡的錯誤回傳.
我知道如果是像URL 這種直接就請求url打錯的會走catch那條.

所以想了解,如果在一切請求資訊都沒錯誤,純粹是token過期或是權限被拒的狀態下,這種後端自己有做錯誤回傳碼和訊息的Axios該怎麼設定比較好呢?
因為有code 403和其他code分別做不同處理的需求
還請各位大大幫忙解惑

froce iT邦大師 1 級 ‧ 2021-12-28 16:34:20 檢舉
檢查寫在 if(response.data.code === 200) {} 區塊啊。
要不然就在後端 return 403 Forbidden。
或甚至寫自訂的 HTTP Status
https://stackoverflow.com/questions/7996569/can-we-create-custom-http-status-codes
samuraigo iT邦新手 4 級 ‧ 2021-12-28 16:59:30 檢舉
感謝大大回覆,我們後端好像是寫自訂的 HTTP Status 他回傳code會自帶一個message說明原因
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2
㊣浩瀚星空㊣
iT邦大神 1 級 ‧ 2021-12-28 17:52:50
最佳解答

正常來說,如果後端有送錯誤的HTTP Status 如401 500 404

其實你這段程式會跑到 catch 那邊去。
因為它會視為請求錯誤。

那個回傳的 error 還是可以拿到回傳值的。你可以先確定一下。
我當時也是為這問題煩腦過。
就只有200的才能正常拿到回傳值。

後來有發現只要是固定的錯誤狀態回應。都會視為請求失敗。
才會去拿catch那個回應值查看看。果然被回傳在這裏了。

samuraigo iT邦新手 4 級 ‧ 2021-12-28 19:56:03 檢舉

感謝大大,真的是這樣耶!!剛又交叉測試一下,順便看了另外一個影片,發現原來後端處理的錯誤都跑到catch去了,唯獨200的會走try的成功路線.
補個影片大概11:15左右
看了才知道,原來error可以.response.xxx 因為直接在VSCode裡沒有error的下拉response選項,以為就只能console出error而已><

1
galaxian85
iT邦新手 4 級 ‧ 2021-12-29 10:12:28

你這個狀況是因為 axios 預設會把200以外的 http status code 都當作 error 拋出
所以200以外都要在 catch 區段處理

其實你可以在呼叫 axios 的時候給他第二個參數{validateStatus:}
裡面可以指定哪些 status code 不拋出 error

以下是官網的範例

axios.get('/user/12345', {
  validateStatus: function (status) {
    // Resolve only if the status code is less than 500
    return status < 500;
  }
})

這樣可以把處理的邏輯一起寫在 try block 裡面
會是比較好一點的做法

samuraigo iT邦新手 4 級 ‧ 2022-01-03 16:30:10 檢舉

哇!原來還有這個方式,感謝大大,等等來試一下!

我要發表回答

立即登入回答