为什么在我的单页面应用程序中获取错误没有堆栈跟踪?

时间:2017-05-05 09:15:06

标签: javascript reactjs error-handling stack-trace fetch-api

我有两个简单的包装器来处理单页面应用程序中的请求。如果响应不正确(不在200-300范围内),一个包装fetch并抛出错误:

const fetchy = (...args) =>
  fetch(...args).then(response => {
    if (response.ok) {
      return response
    }

    throw new Error(response.statusText)
  })

export default fetchy

一个包装fetchy并用于GET请求:

const get = endpoint => {
  const headers = new Headers({ Authorization: `Bearer ${TOKEN}` })
  const init = { method: 'GET', headers }

  return fetchy(endpoint, init)
}

现在我在这样的动作中使用它们(这是redux-thunk动作创建者):

export const fetchArticles = () => dispatch => {
  dispatch({ type: types.FETCH_ARTICLES })

  return get(endpoints.ARTICLES)
    .then(response => response.json())
    .then(data => normalize(data.items, [schemas.articles]))
    .then(normalized => dispatch(fetchArticlesSuccess(normalized)))
    // fetch errors caught here do not have error.stack
    .catch(error => dispatch(fetchArticlesFail(error)))
}

所以我在抓取本身(网络错误)和从fetchy包装器返回的错误(api错误)中捕获了两个错误。问题是fetch中捕获的网络错误(fetchArticles)不包含堆栈跟踪。所以error.stack不存在。这搞砸了我的错误报告。

这是一个有效的错误,error instanceof Error === trueerror.message === 'Failed to fetch'。那么为什么这个错误没有堆栈跟踪?我该如何解决?似乎我可以在fetchy中添加一个错误回调并在那里重新抛出任何错误,但这对我来说似乎很奇怪(但也许我错了)。

2 个答案:

答案 0 :(得分:2)

异步创建获取错误&与特定的JavaScript行没有直接关系。虽然我同意如果包含提取呼叫的行会有所帮助。我已经为此https://bugs.chromium.org/p/chromium/issues/detail?id=718760

提交了一个错误

作为一种解决方法,您可以捕获获取错误,并在堆栈中没有数字时抛出新错误:

function fetchy(...args) {
  return fetch(...args).catch(err => {
    if (!err.stack.match(/\d/)) throw TypeError(err.message);
    throw err;
  }).then(response => {
    if (response.ok) return response;
    throw Error(response.statusText);
  });
}

以下是运行http://jsbin.com/qijabi/edit?js,console

的示例

答案 1 :(得分:2)



最近,我遇到了同样的错误。生产渠道在短短2个月内记录了大约500次此错误,这确实很令人讨厌。我们的是Rails应用程序,其前端由react驱动。

这是我们案中正在发生的事情。页面加载后,刷新按钮变为十字按钮,现在,如果在此页面加载期间正在进行一些api请求,并且用户单击此十字按钮,则chrome浏览器会抛出此错误。在相同的情况下,Firefox在尝试获取资源时会抛出NetworkError。这并不是我们真正要担心的问题,因此我们决定通过使用sentry的ignoreErrors属性来使哨兵忽略此错误。

Sentry.init({
  dsn: "sentry_dsn",
  ignoreErrors: [
    'TypeError: Failed to fetch',
    'TypeError: NetworkError when attempting to fetch resource.'
  ],
});


注意:
CORS 错误也会导致无法提取,请注意这一点。 同样,我们决定使用哨兵的beforeSend回调忽略在400到426之间的statusCode错误。

我花了几天的时间试图找到此错误。希望这对某人有帮助。

我最初在此页面上写了此回复-https://forum.sentry.io/t/typeerror-failed-to-fetch-reported-over-and-overe/8447/2

谢谢