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. |