Exception-Died
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/Exception/Died.pm view on Meta::CPAN
my $pkg = shift;
my $callpkg = caller;
while (my $name = shift @_) {
if ($name eq '%SIG') {
# Undef die hook
$SIG{__DIE__} = '';
};
};
return TRUE;
};
=head1 CONSTRUCTORS
=over
=item catch(I<>) : Self|$@
This method overwrites the default C<catch> constructor. It works as method
from base class and has one exception in its behavior.
my $e = CLASS->catch;
If the popped value is an C<Exception::Died> object and has an attribute
C<catch_can_rebless> set, this object is reblessed to class I<$class> with its
attributes unchanged. It is because original L<Exception::Base>-E<gt>C<catch>
method doesn't change exception class but it should be changed if
C<Exception::Died> handles C<$SIG{__DIE__}> hook.
use Exception::Base
'Exception::Fatal' => { isa => 'Exception::Died' },
'Exception::Simple' => { isa => 'Exception::Died' };
use Exception::Died '%SIG' => 'die';
eval { die "Died\n"; };
my $e = Exception::Fatal->catch;
print ref $e; # "Exception::Fatal"
eval { Exception::Simple->throw; };
my $e = Exception::Fatal->catch;
print ref $e; # "Exception::Simple"
=back
=cut
# Rebless Exception::Died into another exception class
sub catch {
my $self = shift;
my $class = ref $self ? ref $self : $self;
my $e = $self->SUPER::catch(@_);
# Rebless if called as Exception::DiedDerivedClass->catch()
if (do { local $@; local $SIG{__DIE__}; eval { $e->isa(__PACKAGE__) } }
and ref $e ne $class and $e->{catch_can_rebless})
{
bless $e => $class;
};
return $e;
};
=head1 METHODS
=over
=item _collect_system_data(I<>) : Self
Collect system data and fill the attributes of exception object. This method
is called automatically if exception if thrown. This class overrides the
method from L<Exception::Base> class.
See L<Exception::Base>.
=back
=cut
# Collect system data
sub _collect_system_data {
my $self = shift;
if (not ref $@) {
$self->{eval_error} = $@;
while ($self->{eval_error} =~ s/\t\.\.\.propagated at (?!.*\bat\b.*).* line \d+( thread \d+)?\.\n$//s) { }
$self->{eval_error} =~ s/( at (?!.*\bat\b.*).* line \d+( thread \d+)?\.?)?\n$//s;
$self->{eval_error} = undef if $self->{eval_error} eq '';
}
elsif (do { my $e = $@; local $@; local $SIG{__DIE__}; eval { $e->isa('Exception::Died') } }) {
$self->{eval_error} = $@->{eval_error};
$self->{eval_error} = undef if defined $self->{eval_error} and $self->{eval_error} eq '';
}
else {
$self->{eval_error} = undef;
};
return $self->SUPER::_collect_system_data(@_);
};
=head1 FUNCTIONS
=over
=item __DIE__()
This is a hook function for $SIG{__DIE__}. This hook can be enabled with pragma:
use Exception::Died '%SIG';
or manually, i.e. for local scope:
{
local $SIG{__DIE__};
Exception::Died->import('%SIG');
# ...
view all matches for this distributionview release on metacpan - search on metacpan
( run in 1.442 second using v1.00-cache-2.02-grep-82fe00e-cpan-3b7f77b76a6c )