line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package BerkeleyDB::Easy::Error;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
5
|
use strict;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
34
|
|
4
|
1
|
|
|
1
|
|
6
|
use warnings;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
6
|
use BerkeleyDB::Easy::Common;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
321
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our (@ISA, @EXPORT, %EXPORT_TAGS, %Errors);
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
BEGIN {
|
11
|
1
|
|
|
1
|
|
330
|
constant->import({ CODE => 0, DESC => 1, SKIP => 3 });
|
12
|
|
|
|
|
|
|
}
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
BEGIN {
|
15
|
1
|
|
|
1
|
|
18
|
@ISA = qw(Exporter);
|
16
|
1
|
|
|
|
|
2
|
@EXPORT = ();
|
17
|
1
|
|
|
|
|
4
|
%EXPORT_TAGS = (
|
18
|
|
|
|
|
|
|
subs => [qw(_exception _throw _assign _const _lookup _caller _carp)],
|
19
|
|
|
|
|
|
|
);
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# All our constants get BDB_ prefix. And they're dualvars, with neg
|
22
|
|
|
|
|
|
|
# values to avoid stepping on toes.
|
23
|
1
|
|
|
|
|
10
|
%Errors = (
|
24
|
|
|
|
|
|
|
BDB_DEFAULT => [-900, q(Default error) ],
|
25
|
|
|
|
|
|
|
BDB_UNKNOWN => [-404, q(Unknown error) ],
|
26
|
|
|
|
|
|
|
BDB_PLACE => [-666, q(Placeholder error) ],
|
27
|
|
|
|
|
|
|
BDB_HANDLE => [-902, q(Failed to create BerkeleyDB handle) ],
|
28
|
|
|
|
|
|
|
BDB_TYPE => [-901, q(Invalid BerkeleyDB database type) ],
|
29
|
|
|
|
|
|
|
BDB_FLAG => [-903, q(Invalid options flag) ],
|
30
|
|
|
|
|
|
|
BDB_PARAM => [-904, q(Invalid options parameter) ],
|
31
|
|
|
|
|
|
|
BDB_CONST => [-905, q(Invalid constant function) ],
|
32
|
|
|
|
|
|
|
);
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Create constants and make them available for export under the
|
35
|
|
|
|
|
|
|
# 'errors' tag.
|
36
|
1
|
|
|
|
|
5
|
for my $name (keys %Errors) {
|
37
|
8
|
|
|
|
|
13
|
my $code = $Errors{$name}->[CODE];
|
38
|
8
|
|
|
|
|
173
|
constant->import($name, Scalar::Util::dualvar($code, $name));
|
39
|
8
|
|
|
|
|
10
|
push @{$EXPORT_TAGS{errors}}, $name;
|
|
8
|
|
|
|
|
21
|
|
40
|
|
|
|
|
|
|
}
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# Export everything.
|
43
|
1
|
|
|
|
|
3
|
push @EXPORT, map @{$EXPORT_TAGS{$_}}, keys %EXPORT_TAGS;
|
|
2
|
|
|
|
|
177
|
|
44
|
|
|
|
|
|
|
}
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
#
|
47
|
|
|
|
|
|
|
# Define the attributes for exception objects. _install called with a
|
48
|
|
|
|
|
|
|
# single argument as done here creates a simple named accessor
|
49
|
|
|
|
|
|
|
#
|
50
|
|
|
|
|
|
|
for (qw(code name time level desc detail package file line sub trace)) {
|
51
|
|
|
|
|
|
|
__PACKAGE__->_install($_);
|
52
|
|
|
|
|
|
|
}
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
#
|
55
|
|
|
|
|
|
|
# Stringify an exception object. Create default message if none is set.
|
56
|
|
|
|
|
|
|
#
|
57
|
|
|
|
|
|
|
sub stringify {
|
58
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
59
|
|
|
|
|
|
|
|
60
|
0
|
|
0
|
|
|
|
$self->{message} ||= join q(. ), grep $_,
|
61
|
|
|
|
|
|
|
$self->{desc},
|
62
|
|
|
|
|
|
|
$self->{detail};
|
63
|
|
|
|
|
|
|
|
64
|
0
|
|
0
|
|
|
|
$self->{string} ||= sprintf q([%s] %s (%d): %s %s),
|
65
|
|
|
|
|
|
|
$self->{sub},
|
66
|
|
|
|
|
|
|
$self->{name},
|
67
|
|
|
|
|
|
|
$self->{code},
|
68
|
|
|
|
|
|
|
$self->{message},
|
69
|
|
|
|
|
|
|
$self->{trace};
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
0
|
0
|
|
sub numberify { shift->{code} }
|
73
|
|
|
|
|
|
|
|
74
|
1
|
|
|
|
|
5
|
use overload fallback => 1,
|
75
|
|
|
|
|
|
|
q("") => q(stringify),
|
76
|
1
|
|
|
1
|
|
1645
|
q(0+) => q(numberify);
|
|
1
|
|
|
|
|
1148
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
#
|
79
|
|
|
|
|
|
|
# Throw an exception. First, get it's severity level and ignore it if
|
80
|
|
|
|
|
|
|
# appropriate. Otherwise call _exception to build the error object and
|
81
|
|
|
|
|
|
|
# _log to log it and warn/die as necessary.
|
82
|
|
|
|
|
|
|
#
|
83
|
|
|
|
|
|
|
sub _throw {
|
84
|
0
|
|
|
0
|
|
|
my ($self, $error, $extra, $flag) = @_;
|
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
DEBUG and do {
|
87
|
|
|
|
|
|
|
my $code = int($error) || q(?);
|
88
|
|
|
|
|
|
|
$self->_debug(qq(Throwing "$error" ($code)));
|
89
|
|
|
|
|
|
|
};
|
90
|
|
|
|
|
|
|
|
91
|
0
|
|
|
|
|
|
my $level = $self->_assign($error);
|
92
|
0
|
0
|
|
|
|
|
if ($level == BDB_IGNORE) {
|
93
|
0
|
|
|
|
|
|
TRACE and $self->_trace(qq(Ignoring exception: $error));
|
94
|
0
|
|
|
|
|
|
return;
|
95
|
|
|
|
|
|
|
}
|
96
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
my $exc = $self->_exception($error, $extra, $flag);
|
98
|
0
|
|
|
|
|
|
$exc->{level} = $level;
|
99
|
0
|
|
|
|
|
|
$self->_log($level, $exc);
|
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
$exc;
|
102
|
|
|
|
|
|
|
}
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
#
|
105
|
|
|
|
|
|
|
# Build an exception.
|
106
|
|
|
|
|
|
|
# (Internal method, used by _throw)
|
107
|
|
|
|
|
|
|
#
|
108
|
|
|
|
|
|
|
sub _exception {
|
109
|
0
|
|
|
0
|
|
|
my ($self, $error, $extra, $flag) = @_;
|
110
|
|
|
|
|
|
|
|
111
|
0
|
|
0
|
0
|
|
|
our $HiRes ||= !!$self->_try(sub { require Time::HiRes });
|
|
0
|
|
|
|
|
|
|
112
|
0
|
0
|
0
|
|
|
|
my %exc = (
|
113
|
|
|
|
|
|
|
time => ($HiRes ? Time::HiRes::time() : time),
|
114
|
|
|
|
|
|
|
code => (int $error || int BDB_UNKNOWN),
|
115
|
|
|
|
|
|
|
);
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Populate package, file, line and sub attributes.
|
118
|
|
|
|
|
|
|
# If VERBOSE, get a full stack trace.
|
119
|
0
|
|
|
|
|
|
my $caller = $self->_caller(SKIP);
|
120
|
0
|
|
|
|
|
|
$exc{$_} = $caller->{$_} for qw(package file line sub);
|
121
|
0
|
|
|
|
|
|
$exc{trace} = BDB_VERBOSE
|
122
|
|
|
|
|
|
|
? $self->_carp
|
123
|
|
|
|
|
|
|
: qq(at $exc{file} line $exc{line}.);
|
124
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
my @detail = $extra;
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# TODO: a lot of this needs to be reworked. Misbehaving parts
|
128
|
|
|
|
|
|
|
# commented out.
|
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# Gnarly logic here to determine where the error came from
|
131
|
|
|
|
|
|
|
# and consolidate diagnostic messages that were squirreled away
|
132
|
|
|
|
|
|
|
# into a nice object. From perlvar:
|
133
|
|
|
|
|
|
|
#
|
134
|
|
|
|
|
|
|
# $! = $OS_ERROR = $ERRNO : current value of the C errno integer.
|
135
|
|
|
|
|
|
|
# $^E = $EXTENDED_OS_ERROR : Error information specific to the current
|
136
|
|
|
|
|
|
|
# operating system. At the moment, this differs from $! under only
|
137
|
|
|
|
|
|
|
# VMS, OS/2, and Win32 (and for MacPerl). On all other platforms,
|
138
|
|
|
|
|
|
|
# $^E is always just the same as $! .
|
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# DB_ prefix means error is from BerkeleyDB (the C library).
|
141
|
|
|
|
|
|
|
# Parse the exception into name and desc.
|
142
|
|
|
|
|
|
|
# If $! or $^E are also set, put them in the 'detail' field.
|
143
|
0
|
0
|
|
|
|
|
if ($error =~ /^DB_/) {
|
|
|
0
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
@exc{qw(name desc)} = $error =~ /^(DB_\w+):\s*(.+?)\.?$/;
|
145
|
0
|
0
|
0
|
|
|
|
push @detail, $!, ($^E ne $! and $^E) unless $flag;
|
146
|
|
|
|
|
|
|
}
|
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# Perl/OS error. Look up name from errno. Put $^E into 'detail'.
|
149
|
|
|
|
|
|
|
# If $flag is set, we never localized $! (due to optimization setting)
|
150
|
|
|
|
|
|
|
# so its value could be stale. In that case, skip this check.
|
151
|
|
|
|
|
|
|
# elsif ($! and not $flag) {
|
152
|
|
|
|
|
|
|
# @exc{qw(name desc)} = ($self->_lookup($!), $!);
|
153
|
|
|
|
|
|
|
# push @detail, ($^E ne $! and $^E);
|
154
|
|
|
|
|
|
|
# }
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Extended OS error. Usually won't appear without $!, but handle the
|
157
|
|
|
|
|
|
|
# possibility just in case. If $flag is set, we never localized $^E.
|
158
|
|
|
|
|
|
|
# elsif ($^E and not $flag) {
|
159
|
|
|
|
|
|
|
# @exc{qw(name desc)} = ($self->_lookup($^E), $^E);
|
160
|
|
|
|
|
|
|
# }
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# BDB_ prefix means error was generated internally.
|
163
|
|
|
|
|
|
|
elsif ($error =~ /^BDB_/) {
|
164
|
0
|
|
|
|
|
|
@exc{qw(name desc)} = ($error, $Errors{$error}->[DESC]);
|
165
|
|
|
|
|
|
|
}
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# Fallback. Not sure where error originated.
|
168
|
|
|
|
|
|
|
else {
|
169
|
0
|
|
|
|
|
|
@exc{qw(name desc)} = ($self->_lookup($error), $error);
|
170
|
|
|
|
|
|
|
}
|
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# BerkeleyDB.pm error. Should only happen when there's a BerkeleyDB
|
173
|
|
|
|
|
|
|
# (C library) error during initialization. In that case, the BDB.pm
|
174
|
|
|
|
|
|
|
# error global will usually contain additional info.
|
175
|
0
|
0
|
|
|
|
|
if ($BerkeleyDB::Error) {
|
176
|
0
|
|
|
|
|
|
my $match = qr/(?::\s*)?([^:]+?)\.?$/;
|
177
|
0
|
|
|
|
|
|
my ($err ) = $BerkeleyDB::Error =~ $match;
|
178
|
0
|
|
|
|
|
|
my ($desc) = $exc{desc} =~ $match;
|
179
|
0
|
0
|
|
|
|
|
push @detail, $err if $err ne $desc;
|
180
|
|
|
|
|
|
|
}
|
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# @detail may have accumulated multiple messages. Join them into one str.
|
183
|
0
|
|
|
|
|
|
$exc{detail} = join q(. ), map ucfirst, grep $_, @detail;
|
184
|
|
|
|
|
|
|
|
185
|
0
|
|
|
|
|
|
bless \%exc, $self->_Error;
|
186
|
|
|
|
|
|
|
}
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
#
|
189
|
|
|
|
|
|
|
# Look up or set the severity level of an error. Sets the level when the
|
190
|
|
|
|
|
|
|
# second argument ($level) is provided. This is done in the constructor
|
191
|
|
|
|
|
|
|
# if the user opts to assign non-default severity levels to one or more
|
192
|
|
|
|
|
|
|
# errors when a handle is created.
|
193
|
|
|
|
|
|
|
#
|
194
|
|
|
|
|
|
|
sub _assign {
|
195
|
0
|
|
|
0
|
|
|
my ($self, $error, $level) = @_;
|
196
|
0
|
0
|
|
|
|
|
return BDB_ERROR unless ref $self;
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Look up error code from string
|
199
|
0
|
0
|
|
|
|
|
$error = $self->_const($error) if not int $error;
|
200
|
0
|
|
|
|
|
|
my $code = int $error;
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# The BerkeleyDB.pm handle object is inside-out since it's an XS library.
|
203
|
|
|
|
|
|
|
# Our handle is the same object reblessed into our class, so we can't
|
204
|
|
|
|
|
|
|
# store any attributes on it. Instead, look up the address and use it as
|
205
|
|
|
|
|
|
|
# the key for a class-global %Config hash, where we store instance
|
206
|
|
|
|
|
|
|
# settings.
|
207
|
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
my $handle = $self->_handle->[0];
|
209
|
0
|
|
0
|
|
|
|
our $Config ||= {};
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Set severity level if we got $level
|
212
|
0
|
0
|
|
|
|
|
if ($level) {
|
213
|
1
|
|
|
1
|
|
864
|
no strict 'refs';
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
658
|
|
214
|
0
|
0
|
|
|
|
|
defined ${_Common . q(::Levels)}{$level}
|
|
0
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
or $self->_throw(BDB_FLAG, qq(Invalid error level "$level"));
|
216
|
0
|
|
|
|
|
|
$Config->{$handle}{$code} = $level;
|
217
|
|
|
|
|
|
|
}
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# Return user-supplied severity level or the default.
|
220
|
0
|
0
|
0
|
|
|
|
$Config->{$handle}{$code}
|
221
|
|
|
|
|
|
|
or $Config->{$handle}{int BDB_DEFAULT}
|
222
|
|
|
|
|
|
|
or BDB_ERROR;
|
223
|
|
|
|
|
|
|
}
|
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
#
|
226
|
|
|
|
|
|
|
# Resolve a system error name to its errno integer code.
|
227
|
|
|
|
|
|
|
# (Complement to _lookup. Internal method, used by _assign)
|
228
|
|
|
|
|
|
|
#
|
229
|
|
|
|
|
|
|
# Convenience function for option parsing, for when the user
|
230
|
|
|
|
|
|
|
# gives us a string erorr name instead of an int or dualvar.
|
231
|
|
|
|
|
|
|
#
|
232
|
|
|
|
|
|
|
sub _const {
|
233
|
0
|
|
|
0
|
|
|
my ($self, $name) = @_;
|
234
|
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
|
DEBUG and $self->_debug(qq(Resolving constant: $name));
|
236
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
|
my $caller = $self->_caller(SKIP)->{package};
|
238
|
0
|
|
|
|
|
|
my $fullname = qq(&$caller\::$name);
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# Resolve the name to a coderef. Look in our caller, this module,
|
241
|
|
|
|
|
|
|
# BerkeleyDB, and Errno, in that order.
|
242
|
|
|
|
|
|
|
my $func = $caller->can($name)
|
243
|
|
|
|
|
|
|
|| $self->can($name)
|
244
|
|
|
|
|
|
|
|| do { BerkeleyDB->can($name) }
|
245
|
0
|
0
|
0
|
|
|
|
|| do { require Errno; Errno->can($name) }
|
246
|
|
|
|
|
|
|
or $self->_throw(BDB_CONST, qq(Sub $fullname is undefined));
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Now that we have a coderef, try calling it to get the error code.
|
249
|
|
|
|
|
|
|
# Catch any exceptions and repackage them into an error object.
|
250
|
0
|
|
|
0
|
|
|
my $return = $self->_try(sub { $self->_wrap($func) }, sub {
|
251
|
0
|
|
|
0
|
|
|
my ($error) = $_ =~ /^(.*?)(?: at .+ line \d+)?\.?$/m;
|
252
|
0
|
|
|
|
|
|
$self->_throw(BDB_CONST, qq(Sub $fullname died "$error"));
|
253
|
0
|
|
|
|
|
|
});
|
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
# Make sure what we got is an integer. (Well, this doesn't actually go
|
256
|
|
|
|
|
|
|
# that far, but it's in the ballpark.)
|
257
|
0
|
0
|
|
|
|
|
int $return or $self->_throw(
|
258
|
|
|
|
|
|
|
BDB_CONST, qq(Sub $fullname returned non-integer "$return"),
|
259
|
|
|
|
|
|
|
);
|
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
$return;
|
262
|
|
|
|
|
|
|
}
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
#
|
265
|
|
|
|
|
|
|
# Lookup a system error name from its integer errno code.
|
266
|
|
|
|
|
|
|
# (Complement to _const. Internal method, used by _exception)
|
267
|
|
|
|
|
|
|
#
|
268
|
|
|
|
|
|
|
# Used by _exception to show a user-friendly/googleable error name
|
269
|
|
|
|
|
|
|
# instead of an integer errno. Creates a hash mapping all the exportable
|
270
|
|
|
|
|
|
|
# POSIX constants from Errno. There are a lot, so we delay doing this until
|
271
|
|
|
|
|
|
|
# needed, then cache it.
|
272
|
|
|
|
|
|
|
#
|
273
|
|
|
|
|
|
|
sub _lookup {
|
274
|
0
|
|
|
0
|
|
|
my ($self, $error) = @_;
|
275
|
0
|
|
|
|
|
|
my $code = int $error;
|
276
|
|
|
|
|
|
|
|
277
|
0
|
0
|
|
|
|
|
if ($code) {
|
278
|
0
|
|
|
|
|
|
require Errno;
|
279
|
|
|
|
|
|
|
|
280
|
0
|
|
|
|
|
|
my $posix = (our $Posix ||= {
|
281
|
0
|
|
0
|
|
|
|
map { Errno->$_ => $_ } @{$Errno::EXPORT_TAGS{POSIX}}
|
|
0
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
})->{$code};
|
283
|
0
|
0
|
|
|
|
|
return $posix if $posix;
|
284
|
|
|
|
|
|
|
|
285
|
0
|
|
|
|
|
|
local $! = $code;
|
286
|
1
|
|
|
1
|
|
882
|
my @name = grep $!{$_}, keys %!;
|
|
1
|
|
|
|
|
1579
|
|
|
1
|
|
|
|
|
314
|
|
|
0
|
|
|
|
|
|
|
287
|
0
|
0
|
|
|
|
|
return $name[0] if @name == 1;
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# Otherwise, if @name > 1, the errno is ambigious because multiple
|
290
|
|
|
|
|
|
|
# errors share the same code. Many do, so not a frivolous check.
|
291
|
|
|
|
|
|
|
}
|
292
|
|
|
|
|
|
|
|
293
|
0
|
|
|
|
|
|
$self->_warn(qq(Can't resolve error code "$code"));
|
294
|
0
|
|
|
|
|
|
BDB_UNKNOWN;
|
295
|
|
|
|
|
|
|
}
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
#
|
298
|
|
|
|
|
|
|
# Walk down the callstack until we get the first package that isn't us.
|
299
|
|
|
|
|
|
|
# (Internal method, used by _const and _exception)
|
300
|
|
|
|
|
|
|
#
|
301
|
|
|
|
|
|
|
sub _caller {
|
302
|
0
|
|
|
0
|
|
|
my ($self, $frame) = @_;
|
303
|
0
|
|
|
|
|
|
my $base = $self->_Base;
|
304
|
|
|
|
|
|
|
|
305
|
0
|
|
|
|
|
|
my ($pkg, $file, $line, $sub);
|
306
|
0
|
|
|
|
|
|
while (($pkg, $file, $line, $sub) = (caller $frame++)[0..3]) {
|
307
|
0
|
0
|
|
|
|
|
last if $pkg !~ /$base/;
|
308
|
|
|
|
|
|
|
}
|
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
# Something went wrong.
|
311
|
|
|
|
|
|
|
# Don't $self->_warn again or we'll end up back here.
|
312
|
0
|
0
|
|
|
|
|
warn qq(Can't figure out who called into $base) unless $pkg;
|
313
|
0
|
|
|
|
|
|
{ package => $pkg, file => $file, line => $line, sub => $sub };
|
314
|
|
|
|
|
|
|
}
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
#
|
317
|
|
|
|
|
|
|
# Get a stack trace, excluding packages that belong to this distribution.
|
318
|
|
|
|
|
|
|
# (Internal method, used by _exception)
|
319
|
|
|
|
|
|
|
#
|
320
|
|
|
|
|
|
|
sub _carp {
|
321
|
0
|
|
|
0
|
|
|
my $self = shift;
|
322
|
|
|
|
|
|
|
|
323
|
0
|
|
0
|
|
|
|
our $Classes ||= do {
|
324
|
1
|
|
|
1
|
|
7
|
no strict 'refs';
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
233
|
|
325
|
0
|
|
|
|
|
|
[ map { $self->$_ } @{${_Common . q(::EXPORT_TAGS)}{class}} ];
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
};
|
327
|
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
require Carp;
|
329
|
0
|
|
|
|
|
|
local %Carp::Internal;
|
330
|
0
|
|
|
|
|
|
$Carp::Internal{$_}++ for @$Classes;
|
331
|
0
|
|
|
|
|
|
(my $trace = Carp::longmess()) =~ s/^\s+//;
|
332
|
0
|
|
|
|
|
|
$trace;
|
333
|
|
|
|
|
|
|
}
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
INFO and __PACKAGE__->_info(q(Error.pm finished loading));
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
1;
|