如何在fetch错误中包含已解析的响应和原始响应头

3

我有以下的 promise 链:

return fetch(request)
  .then(checkStatus)
  .then(response => response.json())
  .then(json => ({ response: json }))
  .catch(error => ({ error }))

在这里,checkstatus()会检查请求是否成功,如果失败就返回一个错误。这个错误会被捕获并返回。但问题是我想把response.statusTextresponse.json()的结果都添加到错误信息中。但是,当我解析它时,我会失去原始响应,因为我必须返回response.json(),因为它是一个 promise。

目前,checkstatus的功能如下:

const checkStatus = response => {
  if (response.ok) return response

  const error = new Error('Response is not ok')

  // this works because the response hasn't been parsed yet
  if (response.statusText) error.message = response.statusText

  // an error response from our api will include errors, but these are
  // not available here since response.json() hasn't been called
  if (response.errors) error.errors = response.errors

  throw error
}

export default checkStatus

如何使用 error.message = response.statusTexterror.errors = response.json().errors 返回错误信息?


注:本翻译保留了HTML标签,如需删除请告知。

@Bergi 这个问题特别涉及如何处理fetch中的错误,这可能比它应该的要复杂一些。因此,我认为这个问题应该有自己的答案,而不应该被关闭为更一般的组织问题的重复。 - jib
@jib "问题是,当我解析它时,由于我必须返回response.json(),所以我丢失了链中的原始响应" 正是规范问题的关键。 - Bergi
1
@Bergi 这里提出的解决方案不同,而且我认为更加清晰。 - anon
2个回答

2

这是我用于合理处理fetch错误的辅助函数,fetchOk

let fetchOk = (...args) => fetch(...args)
  .then(res => res.ok ? res : res.json().then(data => {
    throw Object.assign(new Error(data.error_message), {name: res.statusText});
  }));

然后我用“fetch”替换它。

let fetchOk = (...args) => fetch(...args)
  .then(res => res.ok ? res : res.json().then(data => {
    throw Object.assign(new Error(data.error_message), {name: res.statusText});
  }));

fetchOk("https://api.stackexchange.com/2.2/blah")
  .then(response => response.json())
  .catch(e => console.log(e)); // Bad Request: no method found with this name

var console = { log: msg => div.innerHTML += msg + "<br>" };
<div id="div"></div>

它只在出现错误时才加载数据,因此成为直接替代品。

1
我使用新的async/await语法,因为这样读起来更直观易懂:
 async fetchData(request) {
    try {
      const response = await fetch(request)
      const data = await response.json()

      // return the data if the response was ok
      if (response.ok) return { data }

      // otherwise return an error with the error data
      const error = new Error(response.statusText)
      if (data.errors) error.errors = data.errors

      throw error
    } catch (error) {
      return { error }
    }
  }

它使得处理fetch返回的promise和response.json()返回的promise变得非常容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接