| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
=head1 NAME |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
CBT::Exception -- base class for exceptions |
|
4
|
|
|
|
|
|
|
S<$Id: Exception.pm,v 1.2 2003/05/12 22:24:00 rkh Exp $> |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package MyModule::Exception; |
|
9
|
|
|
|
|
|
|
use base CBT::Exception; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
package MyModule; |
|
12
|
|
|
|
|
|
|
... |
|
13
|
|
|
|
|
|
|
if ($failed) |
|
14
|
|
|
|
|
|
|
{ throw MyModule::Exception; } |
|
15
|
|
|
|
|
|
|
... |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
B<CBT::Exception> is a base class for exceptions. It may be used |
|
21
|
|
|
|
|
|
|
as-is or as a base class for other exceptions. It is based on Error.pm |
|
22
|
|
|
|
|
|
|
with enhancements for providing more informative feedback and run-time |
|
23
|
|
|
|
|
|
|
control of feedback levels. |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
At the time of this writing, one really needs two components to use |
|
26
|
|
|
|
|
|
|
exceptions: 1) an exception class, 2) the language extensions which enable |
|
27
|
|
|
|
|
|
|
the try...catch...finally syntax. This module provides a base class for |
|
28
|
|
|
|
|
|
|
(1); `use CBT::Exceptions' for (2). |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
A B<CBT::Exception> instance has these attributes: |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=over 4 |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=item error |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
error is a short (1 line) description of the problem. Consider using $! |
|
37
|
|
|
|
|
|
|
if nothing else. |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=item detail (optional) |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
detail provides more details about the nature of the problem. The |
|
42
|
|
|
|
|
|
|
contents of this field are word-wrapped. |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=item advice (optional) |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
advice provides advice about how to rememdy the error. The contents of |
|
47
|
|
|
|
|
|
|
this field are word-wrapped. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=back 4 |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
When thrown, a B<CBT::Exception> looks like this: |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
! MyModule::Exception occurred: invalid argument |
|
54
|
|
|
|
|
|
|
Detail: you provided 0 for your IQ; the valid range is 1..10 |
|
55
|
|
|
|
|
|
|
Advice: soak your head |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 ROUTINES & METHODS |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=cut |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
package CBT::Exception; |
|
63
|
2
|
|
|
2
|
|
12
|
use strict; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
66
|
|
|
64
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
41
|
|
|
65
|
|
|
|
|
|
|
|
|
66
|
2
|
|
|
2
|
|
2484
|
use CBT::debug; |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
105
|
|
|
67
|
|
|
|
|
|
|
our $VERSION = CBT::debug::RCSVersion( '$Revision: 1.2 $ ' ); |
|
68
|
|
|
|
|
|
|
CBT::debug::identify_file() if ($CBT::debug::trace_uses); |
|
69
|
|
|
|
|
|
|
|
|
70
|
2
|
|
|
2
|
|
12
|
use base qw(Error); |
|
|
2
|
|
|
|
|
18
|
|
|
|
2
|
|
|
|
|
155
|
|
|
71
|
2
|
|
|
2
|
|
2742
|
use Text::Wrap; |
|
|
2
|
|
|
|
|
6586
|
|
|
|
2
|
|
|
|
|
116
|
|
|
72
|
2
|
|
|
2
|
|
14
|
use Carp; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
1091
|
|
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
our $show_stacktrace = $CBT::debug || $ENV{EX_STACKTRACE} || 0; |
|
75
|
|
|
|
|
|
|
our $show_advice = exists $ENV{EX_ADVICE} ? $ENV{EX_ADVICE} : 1; |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub new |
|
79
|
|
|
|
|
|
|
{ |
|
80
|
|
|
|
|
|
|
=pod |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=over |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=item B<::new( {error=E<gt>..., |
|
85
|
|
|
|
|
|
|
detail=E<gt>..., |
|
86
|
|
|
|
|
|
|
advice=E<gt>...} )> |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item B<::new( error, detail, advice )> |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
creates a new exception with the spe |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=back |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
|
95
|
1
|
|
|
1
|
1
|
11
|
my $self = shift; |
|
96
|
1
|
|
|
|
|
2
|
my %ex; |
|
97
|
1
|
50
|
|
|
|
5
|
if (ref $_[0]) # throw Ex ( {...} ) |
|
98
|
|
|
|
|
|
|
{ |
|
99
|
0
|
|
|
|
|
0
|
%ex = %{$_[0]}; |
|
|
0
|
|
|
|
|
0
|
|
|
100
|
0
|
0
|
0
|
|
|
0
|
$ex{error} = $ex{text} if not exists $ex{error} and exists $ex{text}; |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
else # throw Ex ( ... ) |
|
103
|
|
|
|
|
|
|
{ |
|
104
|
1
|
50
|
|
|
|
5
|
$ex{error} = shift if @_; |
|
105
|
1
|
50
|
|
|
|
4
|
$ex{detail} = shift if @_; |
|
106
|
1
|
50
|
|
|
|
7
|
$ex{advice} = shift if @_; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
1
|
50
|
|
|
|
5
|
if (not defined $ex{error}) |
|
110
|
|
|
|
|
|
|
{ |
|
111
|
0
|
0
|
|
|
|
0
|
if ($!) |
|
112
|
0
|
|
|
|
|
0
|
{ $ex{error} = $! } |
|
113
|
|
|
|
|
|
|
else |
|
114
|
|
|
|
|
|
|
{ |
|
115
|
0
|
0
|
|
|
|
0
|
croak("Exception created without error string\n") if $ENV{DEBUG}; |
|
116
|
0
|
|
|
|
|
0
|
$ex{error} = 'unknown error'; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
#$ex{detail} = $! if (not defined $ex{detail} and $!); |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
|
|
122
|
1
|
|
|
|
|
8
|
my @args = (); |
|
123
|
1
|
50
|
|
|
|
4
|
local $Error::Debug = exists $ex{stacktrace} ? $ex{stacktrace} |
|
124
|
|
|
|
|
|
|
: $show_stacktrace; |
|
125
|
1
|
|
|
|
|
2
|
local $Error::Depth = $Error::Depth + 1; |
|
126
|
1
|
|
|
|
|
11
|
$self->SUPER::new(%ex, @args); |
|
127
|
|
|
|
|
|
|
} |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
## INTERNAL FUNCTIONS |
|
132
|
|
|
|
|
|
|
sub stringify($) |
|
133
|
|
|
|
|
|
|
{ |
|
134
|
1
|
|
|
1
|
1
|
108
|
my $self = shift; |
|
135
|
1
|
|
33
|
|
|
11
|
my $r = "! " . (ref($self)||$self) . " occurred: " . $self->error() . "\n"; |
|
136
|
1
|
50
|
|
|
|
6
|
if ( $self->detail() ) |
|
137
|
1
|
|
|
|
|
4
|
{ $r .= "Detail:" . wrap("\t", "\t", $self->detail()) . "\n" } |
|
138
|
1
|
50
|
33
|
|
|
354
|
if ( $show_advice and $self->advice() ) |
|
139
|
1
|
|
|
|
|
4
|
{ $r .= "Advice:" . wrap("\t", "\t", $self->advice()) . "\n" } |
|
140
|
1
|
50
|
|
|
|
259
|
if ( $show_stacktrace ) |
|
141
|
0
|
|
|
|
|
0
|
{ $r .= "Trace:\t" . $self->stacktrace() . "\n"; } |
|
142
|
1
|
|
|
|
|
108
|
return $r; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
1
|
|
|
1
|
1
|
4
|
sub error($) { $_[0]->{error}; } |
|
145
|
2
|
|
|
2
|
1
|
9
|
sub detail($) { $_[0]->{detail}; } |
|
146
|
2
|
|
|
2
|
1
|
10
|
sub advice($) { $_[0]->{advice}; } |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# backward compatibility |
|
149
|
0
|
|
|
0
|
1
|
|
sub text($) { $_[0]->error(); } |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
1; |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=pod |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Error.pm -- where all the hard work's done |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head1 AUTHOR |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Reece Hart E<lt>reece@in-machina.comE<gt> |
|
165
|
|
|
|
|
|
|
http://www.in-machina.com/~reece/ |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=cut |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
## TODO- |
|
172
|
|
|
|
|
|
|
## -- on-the-fly exception class creation, e.g., |
|
173
|
|
|
|
|
|
|
## throw YetUnamedException ('you blew it') by overloading throw? |
|
174
|
|
|
|
|
|
|
## -- consider carefully which exception classes to generate |
|
175
|
|
|
|
|
|
|
## perhaps Dave could research this, using java and python as examples |
|
176
|
|
|
|
|
|
|
## -- -level field to control severity w/ run-time control of |
|
177
|
|
|
|
|
|
|
## warning level and fatal level thresholds. |