jQuery内部のエラー処理について

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.png

なんかあきらかにエラー、って感じですね。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"}');
tanaka20110215_jquery.error2.png

なにやら、さきほどより詳細な情報が表示されました。例外に関する情報がわかるようになったようです。 次は一旦ページをリセットして、次のコードを実行し、例外をcatchしてみましょう。

try {
  jQuery.parseJSON('{key:"value"}');
  console.log('success!');
} catch(e) {
  console.log('姉さん、エラーです');
}
tanaka20110215_jquery.error5.png

console.log('success!');の部分は実行されずに、catch内が実行されました。

Sizzle.error について

セレクタの記述ミスで処理停止するのもjQuery.errorが呼ばれているから、と私は最初考えましたが、違うみたいです。

tanaka20110215_jquery.error3.png

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!';
};

tanaka20110215_jquery.error4.png

先ほどみたいに単純に代入しなかったのは、そうすると多数のエラーが表示されて、Firefoxがハングアップしたようになってしまったからです。あと、このエラー表示では、セレクタのエラー調査は難しそうですね。

まとめ

  • jQuery1.4.1からjQuery.errorが導入されました
  • 例外をcatchしないと、後続の処理は実行されません
  • セレクタの記述ミスも、処理中止になりますが、呼び出しているメソッドはjQuery.errorではなくSizzle.error(=jQuery.find.error)です
  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ