web-dev-qa-db-ja.com

Aureliaでのfetch()のエラー処理

サーバーによってエラーが発生したときに何がうまくいかなかったかについての有用な説明を含む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はpromiseを返すtext()メソッドを提供し、それがなければ幸せなpromiseチェーンを妨害しているため、応答テキストへのアクセスに問題があります。上記のコードは機能せず、Uncaught (in promise)エラーが発生します。

うまくいけば、その応答テキストにアクセスするための良い方法がありますか?

16
AR.

これでうまくいくはずです:

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-素晴らしいテクニックでやっていることが好きです!

12
Jeremy Danyow