50

我々がうまく角度1.6.0まで私たちを務めている私たちの角アプリで約束を解決するためのパターンがあります。角度1.6.0:「おそらく未処理の拒否」エラー

resource.get().$promise 
     .then(function (response) { 
     // do something with the response 
     }, function (error) { 
      // pass the error the the error service 
      return errorService.handleError(error); 
     }); 

そしてここでは、私たちがどのようですカルマでエラーをトリガ:

resourceMock.get = function() { 
     var deferred = $q.defer(); 
     deferred.reject(error); 
     return { $promise: deferred.promise }; 
    }; 

を今、1.6.0にアップデートして、角度が急に「おそらく未処理の拒否」エラーで拒否約束のために(カルマで)私たちのユニットテストに不平を言っています。しかし、私たちはエラーサービスを呼び出す2番目の関数で拒否を処理しています。

ここで角度を探しているのは正確ですか?どのように私たちは拒絶反応を「処理する」ことを望んでいますか?

+1

私はこれもコードベースで気づいた。奇妙なことに、クロムランチャーでスイートを実行するとうまく動作します。 PhantomJSは不平を言う人です。 –

+0

これを取得してアップグレードしただけではない場合は、角度バージョンを確認する方法は次のとおりです: http://stackoverflow.com/questions/16017699/how-can-i-check-which-version-of-angular-イム使用 – hubatish

答えて

55

このコードを設定に追加してください。私は一度同様の問題を抱えていましたが、この回避策はそのトリックでした。

app.config(['$qProvider', function ($qProvider) { 
    $qProvider.errorOnUnhandledRejections(false); 
}]); 
+19

私は、これは単にエラーを隠していることを指摘しなければなりません。開発者によれば、コードにいくつかの問題があります。 –

+0

同意すると、問題は回避されるかもしれませんが、根本的な原因はそのまま残り、開発者は代わりにエラーケースを処理する必要があります。 – Skrew

+0

@SachinSharmaはあなたにすべて言った –

17

あなたが表示するコードは、.thenの呼び出しの前に発生する拒否を処理します。このような状況では、.thenに渡された2番目のコールバックが呼び出され、拒否が処理されます。

の場合、.thenを呼び出す約束が成功した場合、第1コールバックを呼び出します。 このコールバックが例外をスローした場合、または拒否された約束を返す場合、2番目のコールバックは1番目の原因で拒否を処理しないため、この結果の拒否は処理されません。これは、Promises/A+仕様に準拠した実装が約束どおりに機能し、Angular promisesが準拠していることです。

次のコードでこれを説明することができます。あなたも約束/ A +に準拠したノードでそれを実行した場合、あなたが得る

function handle(p) { 
    p.then(
     () => { 
      // This is never caught. 
      throw new Error("bar"); 
     }, 
     (err) => { 
      console.log("rejected with", err); 
     }); 
} 

handle(Promise.resolve(1)); 
// We do catch this rejection. 
handle(Promise.reject(new Error("foo"))); 

rejected with Error: foo 
    at Object.<anonymous> (/tmp/t10/test.js:12:23) 
    at Module._compile (module.js:570:32) 
    at Object.Module._extensions..js (module.js:579:10) 
    at Module.load (module.js:487:32) 
    at tryModuleLoad (module.js:446:12) 
    at Function.Module._load (module.js:438:3) 
    at Module.runMain (module.js:604:10) 
    at run (bootstrap_node.js:394:7) 
    at startup (bootstrap_node.js:149:9) 
    at bootstrap_node.js:509:3 
(node:17426) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: bar 
+0

良い点!はい、意図は.thenの呼び出しの前に発生する拒否を処理することです。この拒否を引き起こすコード(Angular 1.5.9で機能したコード)が元の質問に追加されました。 – Groucho

+1

実際に尋ねられたパターンコードを修正するには? – vip

+4

[OK]を修正すると、$ promise.then(success).catch(error)のようになります。ここでcatchはすべてのエラーをキャッチします。詳細は、[migration]の「Note」セクションを参照してください(https://docs.angularjs.org/guide/migration# migrate1.5to1.6-ng-services- $ http) – vip

16

は、圧延によって、問題を発見Angular 1.5.9に戻り、テストを再実行します。簡単な注入問題でしたが、Angular 1.6.0では代わりに "おそらく未処理の拒否"エラーがスローされ、実際のエラーは難読化されました。

+0

これは現在、コードベースを移行して古い注入依存関係を置き換えているので、私にとって大きな問題です。その難読化を防ぐ方法を見つけて、それが本当の誤りを投げつけるようにしましたか? – ChristopherJ

+0

上記の上の答えは実行中のコードでは修正されますが、Angular 1.5.9にロールバックせずにカルマでエラーをスローすることはできませんでした。 – Groucho

2

私はテスト実行中に同じ動作を観察しました。プロダクションコードがうまく動作し、テストでのみ失敗するのは不思議です。

あなたのテストを幸せにする簡単な解決策は、約束のモックにcatch(angular.noop)を追加することです。それ上記の例の場合にすべき次のようになります。ここで答えを確認してください

resourceMock.get = function() { 
 
    var deferred = $q.defer(); 
 
    deferred.reject(error); 
 
    return { $promise: deferred.promise.catch(angular.noop) }; 
 
};

4

Possibly unhandled rejection in Angular 1.6

をこれは316f60fと修正で修正されましたv1.6.1 releaseに含まれています。

+0

まだ1.6.2に入っています – ACIDSTEALTH

+0

このリンクは質問に答えるかもしれませんが、答えの本質的な部分をここに含めて参考にしてください。リンクされたページが変更された場合、リンクのみの回答は無効になります。 - [レビューから](/レビュー/低品質の投稿/ 18725685) –

+0

@MostafaTorbjørnBergありがとうございました。私は答えを更新しました。 –

2

あなたはerrorOnUnhandledRejectionsをオフにすることによって、問題を隠蔽できましたが、エラーはあなたがちょうどあなたの約束にキャッチを追加する必要があるので、「可能性拒絶反応を扱う」する必要だと言います。

resource.get().$promise 
    .then(function (response) { 
    // do something with the response 
    }).catch(function (error)) { 
     // pass the error the the error service 
     return errorService.handleError(error); 
    }); 

参考:https://github.com/angular-ui/ui-router/issues/2889

+1

これは実際には最高の答えです。考えられるエラーを隠すべきではありません – Ero

10

最初のオプションは、ログ機能をオフにします

しかしこのCengkuru Michaelを示唆したとして$ qProvider構成でerrorOnUnhandledRejectionsを設定することによってそれを無効にすると、エラーを非表示にするだけです。

resource.get().$promise 
    .then(function (response) {}) 
    .catch(function (err) {}); 

、リンク:アンギュラ

0

それはあなたのspeficic状況ではないかもしれないが、私は同様の問題がありました。

私の場合、私はangle-i18nを使用していて、ロケール辞書を非同期で取得していました。問題は、取得していたjsonファイルが間違ってインデントされていた(スペースとタブを混ぜている)ことでした。 GET要求は失敗しなかった。

インデントを修正して問題を解決しました。

関連する問題