JavaScriptのPromiseのエラー
ブラウザのJavaScriptでのグローバルエラーハンドルといえば、window.onerrorです。
window.onerror = function(){
console.log("onerror");
}
で、基本的にはこれだけ設定しといて通常の処理中には特別な時以外にエラー処理はしたくないのですよ。でも、Promiseで発生しているエラーはPromiseで処理しないと吸い込まれてしまうのです。たとえば、以下のような感じ。
new Promise(function(resolve, reject){
throw new Error("raise error");
};
まぁ、onerrorのほうはウンともスンとも言わんのですね。もう一つ。
Promise.reject();
もういっちょ。
var p = Promise.resolve();
p.then(function(){
throw new Error("raise error");
});
WinJSのPromise
さて、Microsoft謹製のWinJSにもWinJS.Promiseが付いていて、こいつにはPromise内で発生したエラーを取得する仕組みが入ってます。それがWinJS.Promise.onerrorってイベントですね。以下のような感じ。
WinJS.Promise.onerror = function(ev){
}
//or
WinJS.Promise.addEventListener("error", function(ev){
}
とりあえず、コンストラクタで例外を投げてみるとちゃんとイベントが発生してくれます。
WinJS.Promise.onerror = function(ev){
console.log("promise error");
}
new WinJS.Promise(function(resolve, reject){
console.log("start");
throw new Error("error");
});
//start
//promise error
rejectもちゃんと受け取れます。
WinJS.Promise.onerror = function(ev){
console.log("promise error");
}
new WinJS.Promise(function(resolve, reject){
console.log("start");
reject("error");
});
//start
//promise error
thenでエラー処理している場合はどうなるのか?
試してみます。
WinJS.Promise.onerror = function(ev){
console.log("promise error");
}
new WinJS.Promise(function(resolve, reject){
console.log("start");
reject("error");
}).then(undefined, function(result){
console.log("catch");
});
//start
//promise error
//promise error
//catch
onerrorイベントが2回発生しています。いったいどのタイミングでイベントが発生しているのか確認してみます。予想はコンストラクタ内のrejectが呼ばれたタイミングと、thenでonrejectedが実行されるタイミングです。
WinJS.Promise.onerror = function (ev) {
console.log("promise error");
}
var p = new WinJS.Promise(function (resolve, reject) {
console.log("start");
reject("error");
console.log("rejected");
})
p.then(undefined, function (result) {
console.log("catch");
});
//start
//promise error
//rejected
//promise error
//catch
"rejected"ってログが"promsise error"の後に出てるので、やっぱりコンストラクタのrejectが呼ばれたときにonerrorイベントが発生しているようです。で、こちらもやっぱり"catch"の前に"promise error"がきてるので"onrejected"が実行される前のようですね。
もうちょい見てみます。
WinJS.Promise.onerror = function (ev) {
console.log("promise error");
}
var p = new WinJS.Promise(function (resolve, reject) {
console.log("start");
reject("error");
console.log("rejected");
})
p.then(undefined, function (result) {
console.log("catch");
});
p.then(undefined, function (result) {
console.log("catch2");
});
//start
//promise error
//rejected
//promise error
//catch1
//promise error
//catch2
と、いうことでthenでエラー処理しててもあんまり関係がなくって、エラーが発生した時と、エラー処理が実行されたときにイベントが発生するようです。何回もエラーが発生するってちょっと使いにくいかもですね。