The text of the error message might be useful in the stack trace.

This commit is contained in:
Scott Walters 2011-05-22 23:57:08 -04:00
parent 2cf986ff57
commit 9e557d4a7d

View file

@ -22,12 +22,13 @@ BEGIN {
no warnings 'redefine'; no warnings 'redefine';
my $old_fatal = *WebGUI::Session::Log::fatal{CODE}; my $old_fatal = *WebGUI::Session::Log::fatal{CODE} || sub { };
*WebGUI::Session::Log::fatal = sub { *WebGUI::Session::Log::fatal = sub {
my $self = shift; my $self = shift;
my $message = shift; my $message = shift;
$self->{_stacktrace} = $StackTraceClass->new; $self->{_stacktrace} ||= $StackTraceClass->new; # favor the first stack trace
$self->{_message} ||= $message;
$old_fatal->($self, $message, @_); $old_fatal->($self, $message, @_);
}; };
@ -36,7 +37,8 @@ BEGIN {
*WebGUI::Session::Log::error = sub { *WebGUI::Session::Log::error = sub {
my $self = shift; my $self = shift;
my $message = shift; my $message = shift;
$self->{_stacktrace} = $StackTraceClass->new; $self->{_stacktrace} ||= $StackTraceClass->new;
$self->{_message} ||= $message;
$old_error->($self, $message, @_); $old_error->($self, $message, @_);
}; };
@ -52,22 +54,25 @@ sub call {
undef $env->{'webgui.session'}->log->{_stacktrace}; # the stack trace modules do create circular references; this is necessary undef $env->{'webgui.session'}->log->{_stacktrace}; # the stack trace modules do create circular references; this is necessary
# this should also keep us from doing this work twice if we get stacked twice # this should also keep us from doing this work twice if we get stacked twice
my $text = trace_as_string($trace);
my $message = $env->{'webgui.session'}->log->{_message};
delete $env->{'webgui.session'}->log->{_message};
my @previous_html = $res && $res->[2] ? (map ref $_ ? @{ $_ } : $_, $res->[2]) : (); my @previous_html = $res && $res->[2] ? (map ref $_ ? @{ $_ } : $_, $res->[2]) : ();
my $text = trace_as_string($trace);
$env->{'psgi.errors'}->print($text) unless $self->no_print_errors; $env->{'psgi.errors'}->print($text) unless $self->no_print_errors;
my $html = eval { trace_as_html($trace, $env->{'webgui.session'}) }; my $html = eval { trace_as_html($trace, $env->{'webgui.session'}, $message) };
$res = [500, ['Content-Type' => 'text/html; charset=utf-8'], [ utf8_safe($html), @previous_html ] ]; $res = [500, ['Content-Type' => 'text/html; charset=utf-8'], [ utf8_safe($html), @previous_html ] ];
} }
return $res; return $res;
} }
sub trace_as_string { sub trace_as_string {
my $trace = shift; my $trace = shift;
my $message = shift;
my $st = ''; my $st = "$message:\n";
my $first = 1; my $first = 1;
$trace->reset_pointer; $trace->reset_pointer;
while( my $f = $trace->next_frame ) { while( my $f = $trace->next_frame ) {
@ -92,6 +97,7 @@ sub trace_as_html {
my $trace = shift; my $trace = shift;
my $session = shift or die; my $session = shift or die;
my $message = shift;
my %opt = @_; my %opt = @_;
# copied and modified render() from Devel::StackTrace::WithLexicals # copied and modified render() from Devel::StackTrace::WithLexicals
@ -162,7 +168,7 @@ function toggleLexicals(ref) {
</head> </head>
<body> <body>
<h1>Error trace</h1><pre class="message">$msg</pre><ol> <h1>Error trace</h1><pre class="message">$message<br>$msg</pre><ol>
HEAD HEAD
my $accumulated_asset_info = []; # record the stack frames from when we find an asset on the call stack my $accumulated_asset_info = []; # record the stack frames from when we find an asset on the call stack