Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Devel-StackTrace CPAN distribution.

Report information
The Basics
Id: 33519
Status: resolved
Priority: 0/
Queue: Devel-StackTrace

People
Owner: Nobody in particular
Requestors: ianburrell [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: 1.18



Subject: Feature to limit the size of the args displayed
We get stack traces from Mason that are multiple megabytes because we are passing around HTML fragments. This didn't happen with the old version of Mason since Carp defaults to displaying on the first 64 characters of function arguments. It would be nice if Devel::StackTrace had the feature to limit how many characters of arguments were displayed. I think it would be fine to keep the defaults as unlimited. It looks like Carp has a $Carp::MaxArgLen variable to specify the length.
From: ianburrell [...] gmail.com
Here is a patch that implements a $Devel::StackTrace::MaxArgLen variable and uses it to truncate arguments to that length (plus ...). It defaults to 0 (off). Let me know and I can write the tests and documentation.
diff -r 299de5a1f25e lib/Devel/StackTrace.pm --- a/lib/Devel/StackTrace.pm Fri Feb 22 11:09:55 2008 -0800 +++ b/lib/Devel/StackTrace.pm Mon Feb 25 14:53:23 2008 -0800 @@ -3,7 +3,7 @@ use 5.005; use 5.005; use strict; -use vars qw($VERSION); +use vars qw($VERSION $MaxArgLen); use File::Spec; @@ -13,6 +13,7 @@ use overload $VERSION = '1.16'; +$MaxArgLen = 0; sub new { @@ -327,6 +328,10 @@ sub as_string $_ = $self->Devel::StackTrace::_ref_as_string($_) if ref $_; + if ($Devel::StackTrace::MaxArgLen && length($_) > $Devel::StackTrace::MaxArgLen) { + substr($_, $Devel::StackTrace::MaxArgLen) = '...'; + } + s/'/\\'/g; # 'quote' arg unless it looks like a number
Subject: Re: [rt.cpan.org #33519] Feature to limit the size of the args displayed
Date: Mon, 25 Feb 2008 16:58:22 -0600 (CST)
To: Ian Burrell via RT <bug-Devel-StackTrace [...] rt.cpan.org>
From: Dave Rolsky <autarch [...] urth.org>
On Mon, 25 Feb 2008, Ian Burrell via RT wrote: Show quoted text
> > Queue: Devel-StackTrace > Ticket <URL: http://rt.cpan.org/Ticket/Display.html?id=33519 > > > Here is a patch that implements a $Devel::StackTrace::MaxArgLen variable > and uses it to truncate arguments to that length (plus ...). It defaults > to 0 (off).
I'd prefer this be an object constructor parameter like everything else. It could probably also use a corresponding class method in Exception::Class. There's something similar for respect_overload in D::S and E::C. -dave /*=================================================== VegGuide.Org www.BookIRead.com Your guide to all that's veg. My book blog ===================================================*/
Subject: Re: [rt.cpan.org #33519] Feature to limit the size of the args displayed
Date: Tue, 26 Feb 2008 13:29:53 -0800
To: bug-Devel-StackTrace [...] rt.cpan.org
From: "Ian Burrell" <ianburrell [...] gmail.com>
On Mon, Feb 25, 2008 at 2:58 PM, autarch@urth.org via RT > Show quoted text
> I'd prefer this be an object constructor parameter like everything else. > It could probably also use a corresponding class method in > Exception::Class. There's something similar for respect_overload in D::S > and E::C. >
That would be fine. I chose the global variable to be like Carp and be simple. - Ian
From: ianburrell [...] gmail.com
How about this patch? It implements a max_arg_length parameter to Devel::StackTrace which is passed to Devel::StackTraceFrame and used to limit the arguments. I also added some docs and a test.
diff -r 299de5a1f25e -r 778dc4a6d56c lib/Devel/StackTrace.pm --- a/lib/Devel/StackTrace.pm Fri Feb 22 11:09:55 2008 -0800 +++ b/lib/Devel/StackTrace.pm Tue Feb 26 13:48:23 2008 -0800 @@ -12,7 +12,6 @@ use overload fallback => 1; $VERSION = '1.16'; - sub new { @@ -127,7 +126,7 @@ sub _add_frame } push @{ $self->{frames} }, - Devel::StackTraceFrame->new( $c, $args, $self->{respect_overload} ); + Devel::StackTraceFrame->new( $c, $args, $self->{respect_overload}, $self->{max_arg_length} ); } sub _ref_as_string @@ -265,6 +264,8 @@ BEGIN $self->{args} = $_[1]; $self->{respect_overload} = $_[2]; + + $self->{max_arg_lengtH} = $_[3]; return $self; } @@ -327,6 +328,10 @@ sub as_string $_ = $self->Devel::StackTrace::_ref_as_string($_) if ref $_; + if ($self->{max_arg_length} && length($_) > $self->{max_arg_length}) { + substr($_, $self->{max_arg_length}) = '...'; + } + s/'/\\'/g; # 'quote' arg unless it looks like a number @@ -454,6 +459,12 @@ prefer to see the overloaded representat prefer to see the overloaded representation of objects in stack traces, then set this parameter to true. +=item * max_arg_length => $integer + +By default, Devel::StackTrace will display the full length of +arguments (default of 0). This parameter can be set to the maximum length to display +for all arguments. + =back =item * $trace->next_frame diff -r 299de5a1f25e -r 778dc4a6d56c t/01-basic.t --- a/t/01-basic.t Fri Feb 22 11:09:55 2008 -0800 +++ b/t/01-basic.t Tue Feb 26 13:48:23 2008 -0800 @@ -4,7 +4,7 @@ use Test::More; BEGIN { - my $tests = 34; + my $tests = 35; eval { require Exception::Class }; $tests++ if ! $@ && $Exception::Class::VERSION >= 1.09; @@ -256,6 +256,17 @@ if ( $Exception::Class::VERSION && $Exce } +{ + my $trace = max_arg_length('x' x 20); + + my $trace_text = <<"EOF"; +Trace begun at $test_file_name line 1027 +main::max_arg_length('xxxxxxxxxxxxxxxxxxxx') called at t/01-basic.t line 260 +EOF + + is( $trace->as_string, $trace_text, 'trace text' ); +} + SKIP: { skip "Test only runs on Linux", 1 @@ -296,6 +307,10 @@ sub respect_overloading Devel::StackTrace->new( respect_overload => 1 ); } +sub max_arg_length +{ + Devel::StackTrace->new( max_arg_length => 10 ); +} package Test;
From: ianburrell [...] gmail.com
Might work better if the test checked the new behavior and it worked. Try this instead.
diff -r 299de5a1f25e -r 86eb49fafe00 lib/Devel/StackTrace.pm --- a/lib/Devel/StackTrace.pm Fri Feb 22 11:09:55 2008 -0800 +++ b/lib/Devel/StackTrace.pm Tue Feb 26 14:09:58 2008 -0800 @@ -12,7 +12,6 @@ use overload fallback => 1; $VERSION = '1.16'; - sub new { @@ -127,7 +126,7 @@ sub _add_frame } push @{ $self->{frames} }, - Devel::StackTraceFrame->new( $c, $args, $self->{respect_overload} ); + Devel::StackTraceFrame->new( $c, $args, $self->{respect_overload}, $self->{max_arg_length} ); } sub _ref_as_string @@ -265,6 +264,8 @@ BEGIN $self->{args} = $_[1]; $self->{respect_overload} = $_[2]; + + $self->{max_arg_length} = $_[3]; return $self; } @@ -327,6 +328,10 @@ sub as_string $_ = $self->Devel::StackTrace::_ref_as_string($_) if ref $_; + if ($self->{max_arg_length} && length($_) > $self->{max_arg_length}) { + substr($_, $self->{max_arg_length}) = '...'; + } + s/'/\\'/g; # 'quote' arg unless it looks like a number @@ -454,6 +459,12 @@ prefer to see the overloaded representat prefer to see the overloaded representation of objects in stack traces, then set this parameter to true. +=item * max_arg_length => $integer + +By default, Devel::StackTrace will display the full length of +arguments (default of 0). This parameter can be set to the maximum length to display +for all arguments. + =back =item * $trace->next_frame diff -r 299de5a1f25e -r 86eb49fafe00 t/01-basic.t --- a/t/01-basic.t Fri Feb 22 11:09:55 2008 -0800 +++ b/t/01-basic.t Tue Feb 26 14:09:58 2008 -0800 @@ -4,7 +4,7 @@ use Test::More; BEGIN { - my $tests = 34; + my $tests = 35; eval { require Exception::Class }; $tests++ if ! $@ && $Exception::Class::VERSION >= 1.09; @@ -256,6 +256,17 @@ if ( $Exception::Class::VERSION && $Exce } +{ + my $trace = max_arg_length('abcdefghijklmnop'); + + my $trace_text = <<"EOF"; +Trace begun at $test_file_name line 1027 +main::max_arg_length('abcdefghij...') called at t/01-basic.t line 260 +EOF + + is( $trace->as_string, $trace_text, 'trace text' ); +} + SKIP: { skip "Test only runs on Linux", 1 @@ -296,6 +307,10 @@ sub respect_overloading Devel::StackTrace->new( respect_overload => 1 ); } +sub max_arg_length +{ + Devel::StackTrace->new( max_arg_length => 10 ); +} package Test;
From: ianburrell [...] gmail.com
And here is the patch to add Exception::Class->MaxArgLength which passes max_arg_length parameter.
diff -r 9b71c80a0872 -r 0c145db6992e lib/Exception/Class.pm --- a/lib/Exception/Class.pm Tue Feb 26 13:30:49 2008 -0800 +++ b/lib/Exception/Class.pm Tue Feb 26 14:11:43 2008 -0800 @@ -204,6 +204,8 @@ BEGIN __PACKAGE__->mk_classdata('RespectOverload'); __PACKAGE__->RespectOverload(0); + __PACKAGE__->mk_classdata('MaxArgLength'); + __PACKAGE__->MaxArgLength(0); sub Fields { () } } @@ -300,6 +302,7 @@ sub _initialize ignore_package => \@ignore_package, no_refs => $self->NoRefs, respect_overload => $self->RespectOverload, + max_arg_length => $self->MaxArgLength, ); if ( my $frame = $self->trace->frame(0) ) @@ -635,6 +638,19 @@ subclasses but setting it in a subclass subclasses but setting it in a subclass makes it independent thereafter. +=item * MaxArgLength($boolean) + +When a C<Devel::StackTrace> object stringifies, it can limit the +length of arguments displayed. + +Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally, +this method provides a way to tell C<Devel::StackTrace> to limit the +length of arguments. + +This method defaults to 0, for full arguments. As with C<Trace()>, it +is inherited by subclasses but setting it in a subclass makes it +independent thereafter. + =item * Fields This method returns the extra fields defined for the given class, as diff -r 9b71c80a0872 -r 0c145db6992e t/basic.t --- a/t/basic.t Tue Feb 26 13:30:49 2008 -0800 +++ b/t/basic.t Tue Feb 26 14:11:43 2008 -0800 @@ -4,7 +4,7 @@ use strict; use File::Spec; -use Test::More tests => 56; +use Test::More tests => 58; use_ok('Exception::Class'); @@ -364,6 +364,23 @@ sub FieldsException::full_message ok( $classes{TestException}, 'TestException should be in the return from Classes()' ); } +{ + sub throw { TestException->throw( error => 'dead' ); } + + eval { throw('abcdefghijklmnop') }; + my $e = $@; + + like( $e->as_string, qr/'abcdefghijklmnop'/, 'arguments are not truncated by default' ); + + TestException->MaxArgLength(10); + + eval { throw('abcdefghijklmnop') }; + $e = $@; + + like( $e->as_string, qr/'abcdefghij\.\.\.'/, 'arguments are now truncated' ); +} + + sub argh { Exception::Class::Base->throw( error => 'ARGH' );