line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
2
|
|
|
2
|
|
1222
|
use 5.008; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
89
|
|
2
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
59
|
|
3
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
84
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Error::Hierarchy; |
6
|
|
|
|
|
|
|
BEGIN { |
7
|
2
|
|
|
2
|
|
34
|
$Error::Hierarchy::VERSION = '1.103530'; |
8
|
|
|
|
|
|
|
} |
9
|
|
|
|
|
|
|
# ABSTRACT: Support for hierarchical exception classes |
10
|
2
|
|
|
2
|
|
10
|
use Carp; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
147
|
|
11
|
2
|
|
|
2
|
|
1738
|
use Data::UUID; |
|
2
|
|
|
|
|
1749
|
|
|
2
|
|
|
|
|
132
|
|
12
|
2
|
|
|
2
|
|
1811
|
use Sys::Hostname; |
|
2
|
|
|
|
|
2751
|
|
|
2
|
|
|
|
|
126
|
|
13
|
2
|
|
|
2
|
|
14
|
use parent 'Error::Hierarchy::Base'; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
18
|
|
14
|
|
|
|
|
|
|
__PACKAGE__ |
15
|
|
|
|
|
|
|
->mk_boolean_accessors(qw(is_optional acknowledged)) |
16
|
|
|
|
|
|
|
->mk_accessors(qw( |
17
|
|
|
|
|
|
|
message exception_hostname package filename line depth stacktrace uuid |
18
|
|
|
|
|
|
|
)); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# properties() is used for introspection by code that's catching exceptions. |
21
|
|
|
|
|
|
|
# This code can be left generic as each exception class will know its own |
22
|
|
|
|
|
|
|
# properties. This is useful for something like gettext-based error messages. |
23
|
|
|
|
|
|
|
# Of course, each exception class also supports its own message construction |
24
|
|
|
|
|
|
|
# via message() and stringify(). Exception handling code can decide which |
25
|
|
|
|
|
|
|
# message construction system it wants. |
26
|
2
|
|
|
2
|
|
213
|
use constant default_message => 'Died'; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1284
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# sub properties { () } # empty list, base class defines no properties |
29
|
16
|
|
|
16
|
1
|
54
|
sub error_depth { 1 } |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub init { |
32
|
16
|
|
|
16
|
1
|
123801
|
my $self = shift; |
33
|
16
|
100
|
|
|
|
89
|
$self->message($self->default_message) unless $self->message; |
34
|
16
|
50
|
|
|
|
15225
|
$self->depth(0) unless defined $self->depth; |
35
|
16
|
100
|
|
|
|
360
|
$self->is_optional(0) unless defined $self->is_optional; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# init() code is based on Error::new(); we use a slightly different |
38
|
|
|
|
|
|
|
# scheme to set caller information. Error::throw() (our superclass) sets |
39
|
|
|
|
|
|
|
# $Error::Depth. We use $Error::Depth + 1 because we init() got called by |
40
|
|
|
|
|
|
|
# new(), so the call stack is one deeper than $Error::Depth indicates. |
41
|
16
|
|
|
|
|
143
|
my ($package, $filename, $line) = |
42
|
|
|
|
|
|
|
caller($Error::Depth + $self->error_depth + $self->depth); |
43
|
16
|
|
|
|
|
301
|
$self->exception_hostname(hostname()); |
44
|
16
|
100
|
|
|
|
314
|
$self->package($package) unless defined $self->package; |
45
|
16
|
100
|
|
|
|
390
|
$self->filename($filename) unless defined $self->filename; |
46
|
16
|
100
|
|
|
|
347
|
$self->line($line) unless defined $self->line; |
47
|
16
|
|
|
|
|
2420
|
$self->stacktrace(Carp::longmess); |
48
|
16
|
|
|
|
|
17680
|
$self->uuid(Data::UUID->new->create_str); |
49
|
|
|
|
|
|
|
} |
50
|
11
|
|
|
11
|
1
|
244
|
sub get_properties { $_[0]->every_list('PROPERTIES') } |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub properties_as_hash { |
53
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
54
|
0
|
0
|
0
|
|
|
0
|
my %p = map { $_ => (defined $self->$_ ? $self->$_ : 'unknown') } |
|
0
|
0
|
|
|
|
0
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# hm... ask gr... |
57
|
0
|
|
|
|
|
0
|
grep { $_ ne 'package' && $_ ne 'filename' && $_ ne 'line' } |
58
|
|
|
|
|
|
|
$self->get_properties; |
59
|
0
|
0
|
|
|
|
0
|
wantarray ? %p : \%p; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub stringify { |
63
|
4
|
|
|
4
|
1
|
4282
|
my $self = shift; |
64
|
4
|
|
33
|
|
|
20
|
my $message = $self->message || $self->default_message; |
65
|
4
|
0
|
|
|
|
65
|
sprintf $message => map { $self->$_ || 'unknown' } |
|
0
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$self->get_properties; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub transmute { |
70
|
0
|
|
|
0
|
1
|
|
my ($class, $E, %args) = @_; |
71
|
0
|
|
|
|
|
|
bless $E, $class; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# can't just %$E = (%$E, %args) because the accessors might do more than |
74
|
|
|
|
|
|
|
# set a hash value |
75
|
0
|
|
|
|
|
|
while (my ($key, $value) = each %args) { |
76
|
0
|
|
|
|
|
|
$E->$key($value); |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub comparable { |
81
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
82
|
0
|
|
|
|
|
|
$self->stringify; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
1; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
__END__ |