CGI-ExceptionManager
view release on metacpan or search on metacpan
lib/CGI/ExceptionManager/StackTrace.pm view on Meta::CPAN
package CGI::ExceptionManager::StackTrace;
use strict;
use warnings;
# from MENTA and NanoA
sub _escape_html {
my $str = shift;
$str =~ s/&/&/g;
$str =~ s/>/>/g;
$str =~ s/</</g;
$str =~ s/"/"/g;
$str =~ s/'/'/g;
return $str;
}
sub new {
my ($klass, $message) = @_;
my @trace;
for (my $i = 1; my ($package, $file, $line) = caller($i); $i++) {
push @trace, {
file => $file,
line => $line,
func => undef,
};
if (my @c = caller($i + 1)) {
$trace[-1]->{func} = $c[3]
if $c[3];
}
}
if ($message =~ / at ([^ ]+) line (\d+)/
&& ($1 ne $trace[0]->{file} || $2 != $trace[0]->{line})) {
unshift @trace, {
file => $1,
line => $2,
};
}
bless {
message => $message,
trace => \@trace,
}, $klass;
}
sub _build_context {
my ($file, $linenum) = @_;
my $code;
if (-f $file) {
my $start = $linenum - 3;
my $end = $linenum + 3;
$start = $start < 1 ? 1 : $start;
open my $fh, '<:encoding(utf8)', $file
or die "cannot open $file:$!";
my $cur_line = 0;
while (my $line = <$fh>) {
++$cur_line;
last if $cur_line > $end;
next if $cur_line < $start;
$line =~ s|\t| |g;
my @tag = $cur_line == $linenum
? (q{<b style="color: #000;background-color: #f99;">}, '</b>')
: ('', '');
$code .= sprintf(
'%s%5d: %s%s', $tag[0], $cur_line, _escape_html($line),
$tag[1],
);
}
close $file;
}
return $code;
}
sub as_html {
my ($err, %args) = @_;
my $msg = _escape_html($err->{message});
my $out = qq{<!doctype html><head><title>500 Internal Server Error</title><style type="text/css">body { margin: 0; padding: 0; background: rgb(230, 230, 230); color: rgb(44, 44, 44); } h1 { margin: 0 0 .5em; padding: .25em .5em .1em 1.5em; border...
for my $stack (@{$err->{trace}}) {
$out .= join(
'',
'<li>',
$stack->{func} ? _escape_html("in $stack->{func}") : '',
' at ',
$stack->{file} ? _escape_html($stack->{file}) : '',
' line ',
$stack->{line},
q(<pre><code>),
( run in 0.854 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )