Subject: | Exception fields are stored at the same level as internal fields |
Date: | Wed, 11 Nov 2009 22:20:57 +0000 |
To: | bug-exception-class [...] rt.cpan.org |
From: | Alastair Douglas <alastair.douglas [...] gmail.com> |
A Data::Dumper output gives away the fact that the fields you specify
when you automagically create the exception are at the same level of
the hash as the fields that E::C creates for you. Those fields do not
have particularly special names.
Paste output follows - see the effect of using 'trace' as one of the
fields of your Exception (not an unlikely name). The stacktrace
generated by E::C magic is completely obliterated. This could
introduce pretty nasty bugs.
I came across this trying to work out how to add information to an
exception and then re-throw it, without having to subclass E::C::Base
manually.
Altreus
$ perl -MException::Class
package Exception;
use Exception::Class (
Exception => {
fields => [ 'foo' ],
},
Exception::Bar => {
fields => [ 'bar' ],
isa => 'Exception',
}
);
package main;
eval { Exception::Bar->throw( bar => 1 ) };
if( my $e = Exception->caught ) {
use Data::Dumper;
print Dumper( $e );
}
^D
$VAR1 = bless( {
'euid' => '1016',
'uid' => '1016',
'time' => 1257977566,
'file' => '-',
'egid' => '1016 1016',
'package' => 'main',
'message' => '',
'trace' => bless( {
'ignore_class' => [
'Exception::Class::Base'
],
'ignore_package' => [
'Exception::Class'
],
'frames' => [
bless( {
'wantarray' => undef,
'subroutine' => 'Exception::Class::Base::throw',
'hints' => 0,
'args' => [
'Exception::Bar',
'bar',
1
],
'hasargs' => 1,
'bitmask' => '',
'max_arg_length' => 0,
'evaltext' => undef,
'package' => 'main',
'filename' => '-',
'is_require' => undef,
'respect_overload' => 0,
'line' => 15
},
'Devel::StackTraceFrame' ),
bless( {
'wantarray' => undef,
'subroutine' => '(eval)',
'hints' => 256,
'args' => [],
'hasargs' => 0,
'bitmask' => '',
'max_arg_length' => 0,
'evaltext' => undef,
'package' => 'main',
'filename' => '-',
'is_require' => undef,
'respect_overload' => 0,
'line' => 15
},
'Devel::StackTraceFrame' )
],
'max_arg_length' => 0,
'index' => undef,
'no_refs' => 1,
'respect_overload' => 0
}, 'Devel::StackTrace' ),
'bar' => 1,
'pid' => 15751,
'line' => 15,
'gid' => '1016 1016'
}, 'Exception::Bar' );
$ perl -MException::Class
package Exception;
use Exception::Class (
Exception => {
fields => [ 'foo', 'trace' ],
},
Exception::Bar => {
fields => [ 'bar' ],
isa => 'Exception',
}
);
package main;
eval { Exception::Bar->throw( bar => 1, trace => 3 ) };
if( my $e = Exception->caught ) {
use Data::Dumper;
print Dumper( $e );
}
^D
$VAR1 = bless( {
'euid' => '1016',
'uid' => '1016',
'time' => 1257977663,
'file' => 'test',
'egid' => '1016 1016',
'package' => 'main',
'message' => '',
'trace' => 3,
'bar' => 1,
'pid' => 15756,
'line' => 15,
'gid' => '1016 1016'
}, 'Exception::Bar' );