【问题标题】:Why do fetch errors not have a stacktrace in my single page application?为什么在我的单页应用程序中获取错误没有堆栈跟踪?
【发布时间】:2017-10-03 16:51:38
【问题描述】:

我有两个简单的包装器来处理我的单页应用程序中的请求。如果响应不正确(不在 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)))
}

所以我发现了 fetch 本身的错误(网络错误)和从 fetchy 包装器返回的错误(api 错误)。问题是 fetchArticles 中捕获的来自 fetch 的网络错误不包含堆栈跟踪。所以error.stack 不存在。这弄乱了我的错误报告。

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

【问题讨论】:

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


【解决方案1】:

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

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

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 的示例

【讨论】:

  • 感谢您提交错误报告。也是很好的解决方法,我有一个类似的修复,但在链的末尾有.catch,它没有你的修复那么有效。谢谢!
  • 是的,最后的 catch 也可以,但是让它尽可能接近 fetch 意味着它会给你一个更接近你所追求的行号。
【解决方案2】:



最近我遇到了同样的错误。生产频道在短短 2 个月内记录了大约 500 次此错误,这真的很烦人。我们的是一个由 react 提供前端支持的 Rails 应用程序。

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

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


注意:
CORS 错误也会导致获取失败,请注意这一点。 我们还决定使用 sentry 的 beforeSend 回调忽略 statusCode 介于 400 到 426 之间的错误。

我花了几天时间试图找出这个错误。希望这对某人有所帮助。

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

谢谢

【讨论】:

    猜你喜欢
    • 2011-11-11
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 2013-02-23
    • 2017-02-12
    相关资源
    最近更新 更多