Promise例外を含むすべての例外をグローバルにキャッチする方法はありますか。例:
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
alert("Error occured: " + errorMsg);//or any message
return false;
}
var myClass = function(){
}
var pr = new Promise(function(resolve, react){
var myInstance = new myClass();
myInstance.undefinedFunction(); // this will throw Exception
resolve(myInstance);
});
pr.then(function(result){
console.log(result);
});
// i know right will be this:
// pr.then(function(result){
// console.log(result);
// }).catch(function(e){
// console.log(e);
// });
このスクリプトはエラーなしで静かに終了します。 firebugには何もありません。
私の質問は、もし私が間違いをして、それをキャッチするのを忘れたら、グローバルにキャッチする方法はありますか?
更新すると、ほとんどのブラウザでネイティブプロミスが次の処理を実行します。
window.addEventListener("unhandledrejection", function(promiseRejectionEvent) {
// handle error here, for example log
});
先日、これについて議論していました。
Bluebirdでこれを行う方法は次のとおりです。
window.onpossiblyunhandledexception = function(){
window.onerror.apply(this, arguments); // call
}
window.onerror = function(err){
console.log(err); // logs all errors
}
Bluebirdでは、Promise.onPossiblyUnhandledRejection
を使用することもできます。ライブラリはQとは異なり未処理の拒否自体を検出するため、done
の呼び出しは必要ありません(更新2016-私はQのコードを作成し、これを実行します)。
ネイティブプロミスについては-それらはwill最終的にwindow.onerrorまたは新しいハンドラーに報告しますが、仕様プロセスはまだ完了していません-できます ここに従ってください 。
現在、ほとんどのpromise実装は、参照しているタイプの機能を提供していませんが、多くのサードパーティのpromiseライブラリ( Q および bluebird を含む)は、 done()
メソッド。キャッチされていないエラーをキャッチして再スローし、コンソールに出力します。
(Edit:キャッチされない例外を処理するためのBluebirdの機能に関するBenjamin Gruenbaumの回答を参照してください)
そのため、使用する約束はすべて返されるか、.done()
で終了するという経験則に従う必要があります。
pr.then(function(result){
console.log(result);
})
.done();
Q APIリファレンスから引用するには:
done
vs.then
使用法のゴールデンルールは、return
誰かへの約束、またはチェーンがあなたで終わっている場合は、done
で終了します。catch
ハンドラー自体がエラーをスローする可能性があるため、catch
で終了するだけでは不十分です。
これにはまだ少し手間がかかることを理解していますが、これを行うのを忘れることはできますが、特に上記で指摘した理由により、.catch()
およびすべてのエラーを明示的に処理するよりも改善されます。
Node.jsでは、次を使用できます。
process.on('unhandledRejection', (reason, promise) => {
console.error(`Uncaught error in`, promise);
});
ブラウザとNode.js環境の両方で実行できるコードを書いている場合、次のような自己実行機能でコードをラップできます。
var isNode = (typeof process !== 'undefined' && typeof process.on !== 'undefined');
(function(on, unhandledRejection) {
// PUT ANY CODE HERE
on(unhandledRejection, function(error, promise) {
console.error(`Uncaught error in`, promise);
});
// PUT ANY CODE HERE
})(
isNode ? process.on.bind(process) : window.addEventListener.bind(window),
isNode ? "unhandledRejection" : "unhandledrejection"
);
このコードを使用するとどうなりますか:
Node.js環境で実行する場合、ハンドラーはプロセスオブジェクトにアタッチされ、プロミスにキャッチされない例外があるときに実行されます。
ブラウザー環境で実行する場合、ハンドラーはウィンドウオブジェクトにアタッチされ、promiseでキャッチされない例外があり、ブラウザーがunhandledrejection
イベントをサポートするときに実行されます。
unhandledrejection
をサポートしないブラウザー環境で実行すると、キャッチされない例外をキャッチできず、unhandledrejection
イベントハンドラーがトリガーされることはありませんが、キャッチされない例外がない場合のエラー。
ネイティブPromiseを使用している場合、それは非常に簡単です。
必要なのは.catch
だけです。これはどこかを拒否します。
ajax(request).catch(function(rejected){
console.log(rejected);
});
どこかで捕まえなければ、約束のつかまえられないものが現れ続けるでしょう。しかし、どこかで捕まえたら...