【问题标题】:Error handling for fetch() in AureliaAurelia 中 fetch() 的错误处理
【发布时间】:2016-02-20 08:21:36
【问题描述】:

我有一个 API,其中包含对服务器引发错误时出现的问题的有用描述(状态 = 500)。描述作为响应文本的一部分出现。我的客户端代码使用 Aurelia 通过aurelia-fetch-client 使用通用方法调用 api:

function callRemoteService(apiName, timeout) {
  return Promise.race([
    this.http.fetch(apiName),
    this.waitForServer(timeout || 5000)  // throws after x ms
  ])
    .then(response => response.json() )
    .catch(err => {
        if (err instanceof Response) {
          // HERE'S THE PROBLEM.....
          err.text().then(text => {
            console.log('Error text from callRemoteService() error handler: ' + text);
            throw new Error(text)
          });
        } else if (err instanceof Error) {
          throw new Error(err.message);
        } else {
          throw new Error('Unknown error encountered from callRemoteService()');
        }
    });
}

请注意,我想以一致的方式捕获服务器(获取或超时)错误,然后 throw 将简单的错误消息返回给调用视图。我可以成功调用callRemoteService,在返回 500 时捕获错误:

callRemoteService(this.apiName, this.apiTimeout)
  .then(data => {
    console.log('Successfully called \'' + this.apiName +
      '\'! Result is:\n' + JSON.stringify(data, null, 2));
    })
  .catch(err => {
    console.log('Error from \'' + this.apiName + '\':',err)
    });

但是,我无法访问响应文本,因为fetch 提供了返回承诺的text() 方法,这干扰了我原本很高兴的承诺链接。上面的代码不起作用,给我留下了Uncaught (in promise) 错误。

希望有一种访问该响应文本的好方法吗?

【问题讨论】:

  • 是否将catch 放在then 之前(在顶部代码上)有帮助?
  • @dandavis 我已经尝试了几种变体,但都没有运气。然而,Jeremy 将承诺链保留在 race() 中的建议似乎奏效了。

标签: javascript aurelia fetch-api aurelia-fetch-client


【解决方案1】:

这应该可以解决问题:

function callRemoteService(apiName, timeout = 5000) {
  return Promise.race([
    this.http.fetch(apiName)
      .then(
        r => r.json(),
        r => r.text().then(text => throw new Error(text))
      ),
    this.waitForServer(timeout)
  ]);
}

顺便说一句,我喜欢你用 Promise.race 做的事情——好技巧!

【讨论】:

  • 但它使请求处于打开状态和待处理状态,对吗?这样好吗?
  • 哦-我明白了-在超时的情况下,请求仍处于未决状态。不好但没有答案,直到他们在规范中解决问题。 github.com/whatwg/fetch/issues/20github.com/whatwg/fetch/issues/27
  • 这让我很顺利,谢谢。您将承诺链保留在 race() 中的建议是关键。但是,正如您所写的那样,您的解决方案仍然只向调用者返回一个承诺,而不是实际的响应文本。以下调整对我有用:this.http.fetch(apiName).then(r => r.json(), r => r.text().then(text => { throw new Error(text) } )) 如果您更新答案,我会继续接受。再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
  • 2018-03-13
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-12
  • 2017-12-17
相关资源
最近更新 更多