Blog

Exception::Class を Production でつかうときは NoContextInfo(1) しよう

Exception::Class は便利なのですが、このモジュールは本格的に例外的なことがおきたときに例外をあげる用途を意図して設計されているので、スタックトレースをとったりとか pid/gid/uid などを取得するなど、たいていの用途では大袈裟すぎるぐらいの情報をかきあつめてくれます。スタックトレースの取得はスクリプトなどでは問題ないのですが、Plack などをつかったウェブアプリケーションの場合には、非常にスタックがふかくなることがあるため、アクセスが非常におおいサイトでバリデーションエラーなどの際にカジュアルに例外をあげていると、おもったより負荷がかかることがあるので、以下のように $klass->NoContextInfo(1) を指定してあげるとよいでしょう。

use strict;
use warnings;

package My::Exception;

use Exception::Class (
    'My::Exception' => {
        description => 'runtime exception',
    },
);
for my $klass (grep /^My::Exception::/, keys %Exception::Class::CLASSES) {
    $klass->NoContextInfo(1); # ← これを指定しないと stack trace をとる
}

package main;

use Data::Dumper;
eval {
    My::Exception->throw(error => 'oops');
};
warn Dumper($@);