jQuery内部のエラー処理について
週末にソーシャル・ネットワークを観てきました。全編にわたって早口で物語が展開し、前提知識なしで観たので、途中まで起きていることがつかめませんでした。あらすじは調べてから行かれることをオススメします。個人的にところどころに挟んでくる技術トーク(Emacs使いなところや、講義シーンで出るコンピュータの歴史など)が本筋とは関係ない見所です。
今日もjQuery内部の話をちょっとします。最近、jQuery1.2.xを使っているWebページでjQueryのバージョンを最新にしたら動かなくなることがありました。
調査してみたところ、セレクタの記述が間違っていたが、動作していたこと、(憶測になりますが)1.3でセレクタエンジンSizzleが導入され、挙動が変化したこと、jQueryのエラー処理に変更があったことで不具合が起きてしまったようです。
1.4.1からのエラー処理
jQuery1.4.1から jQuery.error() という関数が追加されました。ドキュメントを読むと、プラグイン開発者向けに用意されているインターフェイスらしく、jQueryのソースコード内を検索してもほとんど出てきません。
前回とりあげたjQuery.parseJSON()にJSONじゃない文字列を渡すと、jQuery.errorが呼ばれるみたいなので、まずは呼んでみましょう。
なんかあきらかにエラー、って感じですね。jQuery.errorの実装は次のようになっています。
jQuery-1.5.js 531行目
error: function( msg ) {
throw msg;
},
なるほど、単に例外を投げてるだけなんですね。例外が投げられて、catchしなかった場合、Firebugはこんな風にエラー表示してくれるようです。ドキュメントには、jQuery.errorのカスタマイズ例として、console.error で上書きするコードが載っています。開発時には使えますね。
jQuery.errorをカスタマイズしてみるコード
jQuery.error = console.error;
jQuery.parseJSON('{key:"value"}');
なにやら、さきほどより詳細な情報が表示されました。例外に関する情報がわかるようになったようです。 次は一旦ページをリセットして、次のコードを実行し、例外をcatchしてみましょう。
try {
jQuery.parseJSON('{key:"value"}');
console.log('success!');
} catch(e) {
console.log('姉さん、エラーです');
}
console.log('success!');
の部分は実行されずに、catch内が実行されました。
Sizzle.error について
セレクタの記述ミスで処理停止するのもjQuery.errorが呼ばれているから、と私は最初考えましたが、違うみたいです。
jQuery.errorを上書きしてもシンプルなエラー表示のままです。調べていくと、セレクタのエラー処理は別の場所で定義されていました。
jQuery-1.5.js 3582行目
Sizzle.error = function( msg ) {
throw "Syntax error, unrecognized expression: " + msg;
};
開発時であれば、ここを上書きしてあげれば、セレクタのエラーについても調査することができそうです。SizzleはjQuery定義時の内部的な変数になっていて、jQuery.findに代入されています。(jQuery-1.5.js 4632行目)、上書きしてみます。
jQuery.find.error = function(msg){
console.error(msg); throw 'error!';
};
先ほどみたいに単純に代入しなかったのは、そうすると多数のエラーが表示されて、Firefoxがハングアップしたようになってしまったからです。あと、このエラー表示では、セレクタのエラー調査は難しそうですね。
まとめ
- jQuery1.4.1からjQuery.errorが導入されました
- 例外をcatchしないと、後続の処理は実行されません
- セレクタの記述ミスも、処理中止になりますが、呼び出しているメソッドはjQuery.errorではなくSizzle.error(=jQuery.find.error)です