點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Promise 處理 Error Response

Sam Xiao's Avatar 2021-05-21

RESTful API 除了回傳 200 HTTP Status 與內容外,也會回傳 Error Response 與 Data,Vue 該如何正確處理呢 ?

Version

Vue 3.0.11

Mock API

mock/getBook.js

import { rest } from 'msw'

export default rest.get('/book/:id', (req, res, ctx) => {
  let { id } = req.params

  return res(
    ctx.status(400),
    ctx.json({
      'code': 20001,
      'errMsg': `Book of ID: ${id} is N/A`,
    })
  )
})

假設 /book/:id 會回傳 HTTP status:400,且還包含 codeerrMsg

Composition API

error000

順利讀出 HTTP status、codeerrMsg

<template lang='pug'>
div
  button(@click='onClick') Get Book
div {{ title }}
</template>

<script setup>
import getBook from '/src/api/getBook'

ref: title = ''

let onClick = () => {
  getBook(1)
    .then(x => x.data)
    .then(x => title = x.title)
    .catch(e => {      
      console.error(e.response.status)
      console.error(e.response.data.code)
      console.error(e.response.data.errMsg)
    })
}
</script>

16 行

.catch(e => {      
  console.error(e.response.status)
  console.error(e.response.data.code)
  console.error(e.response.data.errMsg)
})
  • e.response.status 讀取 HTTP status
  • e.response.data.code 讀取回傳 data 的 code
  • e.response.data 讀取回傳 data 的 errMsg

Data 部分都在 e.response.data 底下

Point-free

error000

結果不變,但使用 Point-free 改寫。

<template lang='pug'>
div
  button(@click='onClick') Get Book
div {{ title }}
</template>

<script setup>
import { ref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, andThen as then, path, otherwise, thunkify } from 'ramda'
import { error } from 'wink-fp'
import getBook from '/src/api/getBook'

let title = ref('')

let errorHandling = e => {
  let { response: { status, data: { code, errMsg }}} = e

  console.error(status)
  console.error(code)
  console.error(errMsg)
} 

let onClick = pipe(
  thunkify(getBook)(1),
  then(path(['data', 'title'])),
  then(write(title)),
  otherwise(errorHandling)
)
</script>

16 行

let errorHandling = e => {
  let { response: { status, data: { code, errMsg }}} = e

  console.error(status)
  console.error(code)
  console.error(errMsg)
}

e 解構出 statuscodeerrMsg

Conclusion

  • HTTP status 可從 e.response.status 讀取;而 data 則都在 e.response.data 之下