Exception::Tinyを継承したクラスで例外を搬送する時、スタックバックトレースを表示させるにはどうしたらいいのか
Perlでスタックバックトレースを伴った例外を発生させるにはCarp::confess
を使えばいいわけですが、
下のコードのようにException::Tinyを継承したクラスで例外を発生させる時にconfessを使ってもスタックバックトレースが表示されません。
package MyApp::Exception; use strict; use warnings; use utf8; use Carp qw/confess/; use parent qw/Exception::Tiny/; sub throw { my $class = shift; my %args; if (@_ == 1) { $args{message} = shift; } else { %args = @_; } $args{message} = $class unless defined $args{message} && $args{message} ne ''; ($args{package}, $args{file}, $args{line}) = caller(0); $args{subroutine} = (caller(1))[3]; # die -> confess confess $class->new(%args); }
原因はわかりません!!
他の例外搬送クラスはどうなんでしょうかね。
とりあえず当分evalの中でconfessを呼び出してそれをインスタンス変数に格納する、という強引な方法で対処することにします(
sub throw { my $class = shift; my %args; if (@_ == 1) { $args{message} = shift; } else { %args = @_; } $args{message} = $class unless defined $args{message} && $args{message} ne ''; ($args{package}, $args{file}, $args{line}) = caller(0); $args{subroutine} = (caller(1))[3]; # confessで例外を発生させてその内容を引数に追加 eval { confess 'start trace.' }; $args{trace} = $@; die $class->new(%args); }
追記:
ドキュメントはちゃんと読みましょう!! Carpのドキュメント、バグのところにオブジェクトは受けつかないと書いてありますね。 とりあえず上記の方法かlongmessを格納する方法しかなさそうです。 誰かいいモジュールを知っている方がいらっしゃればぜひ教えていただきたいです。