|
Packit Service |
3b7cb7 |
package Exception::Class::Base;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use strict;
|
|
Packit Service |
3b7cb7 |
use warnings;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
our $VERSION = '1.44';
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use Class::Data::Inheritable 0.02;
|
|
Packit Service |
3b7cb7 |
use Devel::StackTrace 2.00;
|
|
Packit Service |
3b7cb7 |
use Scalar::Util qw( blessed );
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use base qw(Class::Data::Inheritable);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
BEGIN {
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->mk_classdata('Trace');
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->mk_classdata('UnsafeRefCapture');
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->mk_classdata('NoContextInfo');
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->NoContextInfo(0);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->mk_classdata('RespectOverload');
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->RespectOverload(0);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->mk_classdata('MaxArgLength');
|
|
Packit Service |
3b7cb7 |
__PACKAGE__->MaxArgLength(0);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub NoRefs {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
if (@_) {
|
|
Packit Service |
3b7cb7 |
my $val = shift;
|
|
Packit Service |
3b7cb7 |
return $self->UnsafeRefCapture( !$val );
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
else {
|
|
Packit Service |
3b7cb7 |
return $self->UnsafeRefCapture;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub Fields { () }
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use overload
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
# an exception is always true
|
|
Packit Service |
3b7cb7 |
bool => sub {1}, '""' => 'as_string', fallback => 1;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
# Create accessor routines
|
|
Packit Service |
3b7cb7 |
BEGIN {
|
|
Packit Service |
3b7cb7 |
my @fields = qw( message pid uid euid gid egid time trace );
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
foreach my $f (@fields) {
|
|
Packit Service |
3b7cb7 |
my $sub = sub { my $s = shift; return $s->{$f}; };
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
## no critic (TestingAndDebugging::ProhibitNoStrict)
|
|
Packit Service |
3b7cb7 |
no strict 'refs';
|
|
Packit Service |
3b7cb7 |
*{$f} = $sub;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
*error = \&message;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my %trace_fields = (
|
|
Packit Service |
3b7cb7 |
package => 'package',
|
|
Packit Service |
3b7cb7 |
file => 'filename',
|
|
Packit Service |
3b7cb7 |
line => 'line',
|
|
Packit Service |
3b7cb7 |
);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
while ( my ( $f, $m ) = each %trace_fields ) {
|
|
Packit Service |
3b7cb7 |
my $sub = sub {
|
|
Packit Service |
3b7cb7 |
my $s = shift;
|
|
Packit Service |
3b7cb7 |
return $s->{$f} if exists $s->{$f};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $frame = $s->trace->frame(0);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return $s->{$f} = $frame ? $frame->$m : undef;
|
|
Packit Service |
3b7cb7 |
};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
## no critic (TestingAndDebugging::ProhibitNoStrict)
|
|
Packit Service |
3b7cb7 |
no strict 'refs';
|
|
Packit Service |
3b7cb7 |
*{$f} = $sub;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub Classes { Exception::Class::Classes() }
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub throw {
|
|
Packit Service |
3b7cb7 |
my $proto = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$proto->rethrow if ref $proto;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
die $proto->new(@_);
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub rethrow {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
die $self;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub new {
|
|
Packit Service |
3b7cb7 |
my $proto = shift;
|
|
Packit Service |
3b7cb7 |
my $class = ref $proto || $proto;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $self = bless {}, $class;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$self->_initialize(@_);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return $self;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub _initialize {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
my %p = @_ == 1 ? ( error => $_[0] ) : @_;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$self->{message} = $p{message} || $p{error} || q{};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$self->{show_trace} = $p{show_trace} if exists $p{show_trace};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
if ( $self->NoContextInfo ) {
|
|
Packit Service |
3b7cb7 |
$self->{show_trace} = 0;
|
|
Packit Service |
3b7cb7 |
$self->{package} = $self->{file} = $self->{line} = undef;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
else {
|
|
Packit Service |
3b7cb7 |
# CORE::time is important to fix an error with some versions of
|
|
Packit Service |
3b7cb7 |
# Perl
|
|
Packit Service |
3b7cb7 |
$self->{time} = CORE::time();
|
|
Packit Service |
3b7cb7 |
$self->{pid} = $$;
|
|
Packit Service |
3b7cb7 |
$self->{uid} = $<;
|
|
Packit Service |
3b7cb7 |
$self->{euid} = $>;
|
|
Packit Service |
3b7cb7 |
$self->{gid} = $(;
|
|
Packit Service |
3b7cb7 |
$self->{egid} = $);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my @ignore_class = (__PACKAGE__);
|
|
Packit Service |
3b7cb7 |
my @ignore_package = 'Exception::Class';
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
if ( my $i = delete $p{ignore_class} ) {
|
|
Packit Service |
3b7cb7 |
push @ignore_class, ( ref($i) eq 'ARRAY' ? @$i : $i );
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
if ( my $i = delete $p{ignore_package} ) {
|
|
Packit Service |
3b7cb7 |
push @ignore_package, ( ref($i) eq 'ARRAY' ? @$i : $i );
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$self->{trace} = Devel::StackTrace->new(
|
|
Packit Service |
3b7cb7 |
ignore_class => \@ignore_class,
|
|
Packit Service |
3b7cb7 |
ignore_package => \@ignore_package,
|
|
Packit Service |
3b7cb7 |
unsafe_ref_capture => $self->UnsafeRefCapture,
|
|
Packit Service |
3b7cb7 |
respect_overload => $self->RespectOverload,
|
|
Packit Service |
3b7cb7 |
max_arg_length => $self->MaxArgLength,
|
|
Packit Service |
3b7cb7 |
map { $p{$_} ? ( $_ => delete $p{$_} ) : () } qw(
|
|
Packit Service |
3b7cb7 |
frame_filter
|
|
Packit Service |
3b7cb7 |
filter_frames_early
|
|
Packit Service |
3b7cb7 |
skip_frames
|
|
Packit Service |
3b7cb7 |
),
|
|
Packit Service |
3b7cb7 |
);
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my %fields = map { $_ => 1 } $self->Fields;
|
|
Packit Service |
3b7cb7 |
while ( my ( $key, $value ) = each %p ) {
|
|
Packit Service |
3b7cb7 |
next if $key =~ /^(?:error|message|show_trace)$/;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
if ( $fields{$key} ) {
|
|
Packit Service |
3b7cb7 |
$self->{$key} = $value;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
else {
|
|
Packit Service |
3b7cb7 |
Exception::Class::Base->throw(
|
|
Packit Service |
3b7cb7 |
error => "unknown field $key passed to constructor for class "
|
|
Packit Service |
3b7cb7 |
. ref $self );
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub context_hash {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return {
|
|
Packit Service |
3b7cb7 |
time => $self->{time},
|
|
Packit Service |
3b7cb7 |
pid => $self->{pid},
|
|
Packit Service |
3b7cb7 |
uid => $self->{uid},
|
|
Packit Service |
3b7cb7 |
euid => $self->{euid},
|
|
Packit Service |
3b7cb7 |
gid => $self->{gid},
|
|
Packit Service |
3b7cb7 |
egid => $self->{egid},
|
|
Packit Service |
3b7cb7 |
};
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub field_hash {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $hash = {};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
for my $field ( $self->Fields ) {
|
|
Packit Service |
3b7cb7 |
$hash->{$field} = $self->$field;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return $hash;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub description {
|
|
Packit Service |
3b7cb7 |
return 'Generic exception';
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub show_trace {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return 0 unless $self->{trace};
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
if (@_) {
|
|
Packit Service |
3b7cb7 |
$self->{show_trace} = shift;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return exists $self->{show_trace} ? $self->{show_trace} : $self->Trace;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub as_string {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $str = $self->full_message;
|
|
Packit Service |
3b7cb7 |
unless ( defined $str && length $str ) {
|
|
Packit Service |
3b7cb7 |
my $desc = $self->description;
|
|
Packit Service |
3b7cb7 |
$str = defined $desc
|
|
Packit Service |
3b7cb7 |
&& length $desc ? "[$desc]" : '[Generic exception]';
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$str .= "\n\n" . $self->trace->as_string
|
|
Packit Service |
3b7cb7 |
if $self->show_trace;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return $str;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub full_message { $_[0]->message }
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
#
|
|
Packit Service |
3b7cb7 |
# The %seen bit protects against circular inheritance.
|
|
Packit Service |
3b7cb7 |
#
|
|
Packit Service |
3b7cb7 |
## no critic (BuiltinFunctions::ProhibitStringyEval, ErrorHandling::RequireCheckingReturnValueOfEval)
|
|
Packit Service |
3b7cb7 |
eval <<'EOF' if $] == 5.006;
|
|
Packit Service |
3b7cb7 |
sub isa {
|
|
Packit Service |
3b7cb7 |
my ( $inheritor, $base ) = @_;
|
|
Packit Service |
3b7cb7 |
$inheritor = ref($inheritor) if ref($inheritor);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my %seen;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
no strict 'refs';
|
|
Packit Service |
3b7cb7 |
my @parents = ( $inheritor, @{"$inheritor\::ISA"} );
|
|
Packit Service |
3b7cb7 |
while ( my $class = shift @parents ) {
|
|
Packit Service |
3b7cb7 |
return 1 if $class eq $base;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
push @parents, grep { !$seen{$_}++ } @{"$class\::ISA"};
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
return 0;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
EOF
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub caught {
|
|
Packit Service |
3b7cb7 |
my $class = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $e = $@;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return unless defined $e && blessed($e) && $e->isa($class);
|
|
Packit Service |
3b7cb7 |
return $e;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
1;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
# ABSTRACT: A base class for exception objects
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
__END__
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=pod
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=encoding UTF-8
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 NAME
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Exception::Class::Base - A base class for exception objects
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 VERSION
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
version 1.44
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 SYNOPSIS
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use Exception::Class 'MyException';
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
eval { MyException->throw( error => 'I feel funny.' ) };
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
print $@->error;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 DESCRIPTION
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This class is the base class for all exceptions created by
|
|
Packit Service |
3b7cb7 |
L<Exception::Class>. It provides a number of methods for getting information
|
|
Packit Service |
3b7cb7 |
about the exception.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=for Pod::Coverage Classes
|
|
Packit Service |
3b7cb7 |
caught
|
|
Packit Service |
3b7cb7 |
NoRefs
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 METHODS
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->Trace($boolean)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Each C<Exception::Class::Base> subclass can be set individually to include a
|
|
Packit Service |
3b7cb7 |
stacktrace when the C<as_string> method is called. The default is to not
|
|
Packit Service |
3b7cb7 |
include a stacktrace. Calling this method with a value changes this
|
|
Packit Service |
3b7cb7 |
behavior. It always returns the current value (after any change is applied).
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This value is inherited by any subclasses. However, if this value is set for a
|
|
Packit Service |
3b7cb7 |
subclass, it will thereafter be independent of the value in
|
|
Packit Service |
3b7cb7 |
C<Exception::Class::Base>.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Do not call this on the C<Exception::Class::Base> class directly or you'll
|
|
Packit Service |
3b7cb7 |
change it for all exception classes that use L<Exception::Class>, including
|
|
Packit Service |
3b7cb7 |
ones created in modules you don't control.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This is a class method, not an object method.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->UnsafeRefCapture($boolean)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
When a C<Devel::StackTrace> object is created, it walks through the stack and
|
|
Packit Service |
3b7cb7 |
stores the arguments which were passed to each subroutine on the stack. If any
|
|
Packit Service |
3b7cb7 |
of these arguments are references, then that means that the
|
|
Packit Service |
3b7cb7 |
C<Devel::StackTrace> ends up increasing the ref count of these references,
|
|
Packit Service |
3b7cb7 |
delaying their destruction.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally, this
|
|
Packit Service |
3b7cb7 |
method provides a way to tell C<Devel::StackTrace> not to store these
|
|
Packit Service |
3b7cb7 |
references. Instead, C<Devel::StackTrace> replaces references with their
|
|
Packit Service |
3b7cb7 |
stringified representation.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method defaults to false. As with C<Trace>, it is inherited by subclasses
|
|
Packit Service |
3b7cb7 |
but setting it in a subclass makes it independent thereafter.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Do not call this on the C<Exception::Class::Base> class directly or you'll
|
|
Packit Service |
3b7cb7 |
change it for all exception classes that use L<Exception::Class>, including
|
|
Packit Service |
3b7cb7 |
ones created in modules you don't control.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->RespectOverload($boolean)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
When a C<Devel::StackTrace> object stringifies, by default it ignores
|
|
Packit Service |
3b7cb7 |
stringification overloading on any objects being dealt with.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally, this
|
|
Packit Service |
3b7cb7 |
method provides a way to tell C<Devel::StackTrace> to respect overloading.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method defaults to false. As with C<Trace>, it is inherited by subclasses
|
|
Packit Service |
3b7cb7 |
but setting it in a subclass makes it independent thereafter.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Do not call this on the C<Exception::Class::Base> class directly or you'll
|
|
Packit Service |
3b7cb7 |
change it for all exception classes that use L<Exception::Class>, including
|
|
Packit Service |
3b7cb7 |
ones created in modules you don't control.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->MaxArgLength($boolean)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
When a C<Devel::StackTrace> object stringifies, by default it displays the
|
|
Packit Service |
3b7cb7 |
full argument for each function. This parameter can be used to limit the
|
|
Packit Service |
3b7cb7 |
maximum length of each argument.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally, this
|
|
Packit Service |
3b7cb7 |
method provides a way to tell C<Devel::StackTrace> to limit the length of
|
|
Packit Service |
3b7cb7 |
arguments.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method defaults to 0. As with C<Trace>, it is inherited by subclasses but
|
|
Packit Service |
3b7cb7 |
setting it in a subclass makes it independent thereafter.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Do not call this on the C<Exception::Class::Base> class directly or you'll
|
|
Packit Service |
3b7cb7 |
change it for all exception classes that use L<Exception::Class>, including
|
|
Packit Service |
3b7cb7 |
ones created in modules you don't control.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->Fields
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method returns the extra fields defined for the given class, as a list.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Do not call this on the C<Exception::Class::Base> class directly or you'll
|
|
Packit Service |
3b7cb7 |
change it for all exception classes that use L<Exception::Class>, including
|
|
Packit Service |
3b7cb7 |
ones created in modules you don't control.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->throw( $message )
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->throw( message => $message )
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->throw( error => $error )
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method creates a new object with the given error message. If no error
|
|
Packit Service |
3b7cb7 |
message is given, this will be an empty string. It then dies with this object
|
|
Packit Service |
3b7cb7 |
as its argument.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method also takes a C<show_trace> parameter which indicates whether or
|
|
Packit Service |
3b7cb7 |
not the particular exception object being created should show a stacktrace
|
|
Packit Service |
3b7cb7 |
when its C<as_string> method is called. This overrides the value of C<Trace>
|
|
Packit Service |
3b7cb7 |
for this class if it is given.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
The frames included in the trace can be controlled by the C<ignore_class> and
|
|
Packit Service |
3b7cb7 |
C<ignore_package> parameters. These are passed directly to Devel::Stacktrace's
|
|
Packit Service |
3b7cb7 |
constructor. See C<Devel::Stacktrace> for more details. This class B<always>
|
|
Packit Service |
3b7cb7 |
passes C<__PACKAGE__> for C<ignore_class> and C<'Exception::Class'> for
|
|
Packit Service |
3b7cb7 |
C<ignore_package>, in addition to any arguments you provide.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
If only a single value is given to the constructor it is assumed to be the
|
|
Packit Service |
3b7cb7 |
message parameter.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Additional keys corresponding to the fields defined for the particular
|
|
Packit Service |
3b7cb7 |
exception subclass will also be accepted.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->new(...)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method takes the same parameters as C<throw>, but instead of dying simply
|
|
Packit Service |
3b7cb7 |
returns a new exception object.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method is always called when constructing a new exception object via the
|
|
Packit Service |
3b7cb7 |
C<throw> method.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 MyException->description
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the description for the given C<Exception::Class::Base> subclass. The
|
|
Packit Service |
3b7cb7 |
C<Exception::Class::Base> class's description is "Generic exception" (this may
|
|
Packit Service |
3b7cb7 |
change in the future). This is also an object method.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->rethrow
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Simply dies with the object as its sole argument. It's just syntactic
|
|
Packit Service |
3b7cb7 |
sugar. This does not change any of the object's attribute values. However, it
|
|
Packit Service |
3b7cb7 |
will cause C<caller> to report the die as coming from within the
|
|
Packit Service |
3b7cb7 |
C<Exception::Class::Base> class rather than where rethrow was called.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Of course, you always have access to the original stacktrace for the exception
|
|
Packit Service |
3b7cb7 |
object.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->message
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->error
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the error/message associated with the exception.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->pid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the pid at the time the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->uid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the real user id at the time the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->gid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the real group id at the time the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->euid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the effective user id at the time the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->egid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the effective group id at the time the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->time
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the time in seconds since the epoch at the time the exception was
|
|
Packit Service |
3b7cb7 |
thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->package
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the package from which the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->file
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the file within which the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->line
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the line where the exception was thrown.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->context_hash
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns a hash reference with the following keys:
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=over 4
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * time
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * pid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * uid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * euid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * gid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=item * egid
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=back
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->field_hash
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns a hash reference where the keys are any fields defined for the
|
|
Packit Service |
3b7cb7 |
exception class and the values are the values associated with the field in the
|
|
Packit Service |
3b7cb7 |
given object.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->trace
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns the trace object associated with the object.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->show_trace($boolean)
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This method can be used to set whether or not a stack trace is included when
|
|
Packit Service |
3b7cb7 |
the as_string method is called or the object is stringified.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->as_string
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Returns a string form of the error message (something like what you'd expect
|
|
Packit Service |
3b7cb7 |
from die). If the class or object is set to show traces then then the full
|
|
Packit Service |
3b7cb7 |
trace is also included. The result looks like C<Carp::confess>.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head2 $exception->full_message
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Called by the C<as_string> method to get the message. By default, this is the
|
|
Packit Service |
3b7cb7 |
same as calling the C<message> method, but may be overridden by a
|
|
Packit Service |
3b7cb7 |
subclass. See below for details.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 LIGHTWEIGHT EXCEPTIONS
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
A lightweight exception is one which records no information about its context
|
|
Packit Service |
3b7cb7 |
when it is created. This can be achieved by setting C<< $class->NoContextInfo
|
|
Packit Service |
3b7cb7 |
>> to a true value.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
You can make this the default for a class of exceptions by setting it after
|
|
Packit Service |
3b7cb7 |
creating the class:
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
use Exception::Class (
|
|
Packit Service |
3b7cb7 |
'LightWeight',
|
|
Packit Service |
3b7cb7 |
'HeavyWeight',
|
|
Packit Service |
3b7cb7 |
);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
LightWeight->NoContextInfo(1);
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
A lightweight exception does have a stack trace object, nor does it record the
|
|
Packit Service |
3b7cb7 |
time, pid, uid, euid, gid, or egid. It only has a message.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 OVERLOADING
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
C<Exception::Class::Base> objects are overloaded so that stringification
|
|
Packit Service |
3b7cb7 |
produces a normal error message. This just calls the C<< $exception->as_string
|
|
Packit Service |
3b7cb7 |
>> method described above. This means that you can just C<print $@> after an
|
|
Packit Service |
3b7cb7 |
C<eval> and not worry about whether or not its an actual object. It also means
|
|
Packit Service |
3b7cb7 |
an application or module could do this:
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
and this would probably not break anything (unless someone was expecting a
|
|
Packit Service |
3b7cb7 |
different type of exception object from C<die>).
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 OVERRIDING THE as_string METHOD
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
By default, the C<as_string> method simply returns the value C<message> or
|
|
Packit Service |
3b7cb7 |
C<error> param plus a stack trace, if the class's C<Trace> method returns a
|
|
Packit Service |
3b7cb7 |
true value or C<show_trace> was set when creating the exception.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
However, once you add new fields to a subclass, you may want to include those
|
|
Packit Service |
3b7cb7 |
fields in the stringified error.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Inside the C<as_string> method, the message (non-stack trace) portion of the
|
|
Packit Service |
3b7cb7 |
error is generated by calling the C<full_message> method. This can be easily
|
|
Packit Service |
3b7cb7 |
overridden. For example:
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
sub full_message {
|
|
Packit Service |
3b7cb7 |
my $self = shift;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
my $msg = $self->message;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
$msg .= " and foo was " . $self->foo;
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
return $msg;
|
|
Packit Service |
3b7cb7 |
}
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 SUPPORT
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Bugs may be submitted at L<https://github.com/houseabsolute/Exception-Class/issues>.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 SOURCE
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
The source code repository for Exception-Class can be found at L<https://github.com/houseabsolute/Exception-Class>.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 AUTHOR
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
Dave Rolsky <autarch@urth.org>
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=head1 COPYRIGHT AND LICENSE
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This software is copyright (c) 2017 by Dave Rolsky.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
This is free software; you can redistribute it and/or modify it under
|
|
Packit Service |
3b7cb7 |
the same terms as the Perl 5 programming language system itself.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
The full text of the license can be found in the
|
|
Packit Service |
3b7cb7 |
F<LICENSE> file included with this distribution.
|
|
Packit Service |
3b7cb7 |
|
|
Packit Service |
3b7cb7 |
=cut
|