Permalink
Browse files

try to get a more helpful stacktrace even when exceptions are rethrown

this happens frequently with StackTrace + HTTPExceptions, among other
things
  • Loading branch information...
1 parent 94cf6bb commit 8b9811214475cd1df75e8c3fe87ee294ca5fa209 @doy doy committed Dec 19, 2012
Showing with 23 additions and 4 deletions.
  1. +23 −4 lib/Plack/Middleware/StackTrace.pm
@@ -6,6 +6,7 @@ use Devel::StackTrace;
use Devel::StackTrace::AsHTML;
use Try::Tiny;
use Plack::Util::Accessor qw( force no_print_errors );
+use Scalar::Util 'refaddr';
our $StackTraceClass = "Devel::StackTrace";
@@ -18,11 +19,16 @@ sub call {
my($self, $env) = @_;
my $trace;
+ my %seen;
local $SIG{__DIE__} = sub {
- $trace = $StackTraceClass->new(
- indent => 1, message => munge_error($_[0], [ caller ]),
- ignore_package => __PACKAGE__,
- );
+ my $key = _make_key($_[0]);
+ if (!$seen{$key}) {
+ $trace = $StackTraceClass->new(
+ indent => 1, message => munge_error($_[0], [ caller ]),
+ ignore_package => __PACKAGE__,
+ );
+ }
+ $seen{$key} = 1;
die @_;
};
@@ -95,6 +101,19 @@ sub utf8_safe {
$str;
}
+sub _make_key {
+ my ($val) = @_;
+ if (!defined($val)) {
+ return 'undef';
+ }
+ elsif (ref($val)) {
+ return 'ref:' . refaddr($val);
+ }
+ else {
+ return "str:$val";
+ }
+}
+
1;
__END__

3 comments on commit 8b98112

Owner

miyagawa commented on 8b98112 Dec 20, 2012

+0

This would probably address #145

I'm worried about false cache hit with this, but I guess it would make things better for 90% of the rethrow case and maybe worth a try.

Wishlist: is it possible that we update the HTML templates so to tell developers that the stack trace is being pulled from the cache, so that they know that it's either a) the app does rethrow (hit the bell) or b) it's pulling out a wrong information

Owner

miyagawa replied Dec 20, 2012

well, the HTML is being generated in StackTrace::AsHTML so there's not much to control, but...

Owner

doy replied Dec 20, 2012

That's probably not unreasonable. What might be even better would be to provide some way to flip between all of the different exceptions that were thrown (defaulting to the first one that matches the caught exception, as here), but I don't know how doable that is.

Please sign in to comment.