package Catalyst::Plugin::StackTrace; use strict; use warnings; use base qw/Class::Accessor::Fast/; use Devel::StackTrace; use HTML::Entities; use Scalar::Util qw/blessed/; use NEXT; our $VERSION = '0.04'; __PACKAGE__->mk_accessors('_stacktrace'); sub execute { my $c = shift; # NEXT hack is required when extending execute :( local $NEXT::NEXT{ $c, 'execute' }; return $c->NEXT::execute(@_) unless $c->debug; local $SIG{__DIE__} = sub { my $error = shift; # ignore if the error is a Tree::Simple object # because FindByUID uses an internal die several times per request return if ( blessed($error) && $error->isa('Tree::Simple') ); my $ignore_package = [ 'Catalyst::Plugin::StackTrace' ]; my $ignore_class = []; if ( $c->config->{stacktrace}->{verbose} < 2 ) { $ignore_package = [ qw/ Catalyst Catalyst::Action Catalyst::Base Catalyst::Dispatcher Catalyst::Plugin::StackTrace Catalyst::Plugin::Static::Simple NEXT main / ]; $ignore_class = [ qw/ Catalyst::Engine / ]; } my $trace = Devel::StackTrace->new( ignore_package => $ignore_package, ignore_class => $ignore_class, no_refs => 1, respect_overload => 1, ); $c->_stacktrace( [ $trace->frames ] ); }; return $c->NEXT::execute(@_); } sub finalize_error { my $c = shift; $c->NEXT::finalize_error(@_); if ( $c->debug ) { return unless ref $c->_stacktrace eq 'ARRAY'; my $trace = []; for my $frame ( @{ $c->_stacktrace } ) { # only display frames from the user's app unless verbose if ( !$c->config->{stacktrace}->{verbose} ) { my $app = "$c"; $app =~ s/=.*//; next unless $frame->package =~ /^$app/; } push @{$trace}, { pkg => $frame->package, file => $frame->filename, line => $frame->line, }; } # insert the stack trace into the error screen above the "infos" div my $html = qq{
| Package | Line | File |
|---|---|---|
| $pkg | $line | $file |
|
||