1Class::Throwable(3)   User Contributed Perl Documentation  Class::Throwable(3)
2
3
4

NAME

6       Class::Throwable - A minimal lightweight exception class
7

SYNOPSIS

9         use Class::Throwable;
10
11         # simple usage
12         eval {
13             # code code code,
14             if ($something_goes_wrong) {
15                 throw Class::Throwable "Something has gone wrong";
16             }
17         };
18         if ($@) {
19             # we just print out the exception message here
20             print "There has been an exception: " $@->getMessage();
21             # but if we are debugging we get the whole
22             # stack trace as well
23             if (DEBUG) {
24                 print $@->getStackTraceAsString();
25             }
26         }
27
28         # it can be used to catch perl exceptions
29         # and wrap them in a Class::Throwable exception
30         eval {
31             # generate a perl exception
32             eval "2 / 0";
33             # then throw our own with the
34             # perl exception as a sub-exception
35             throw Class::Throwable "Throwing an exception" => $@ if $@;
36         };
37         if ($@) {
38             # setting the verbosity to
39             # 2 gives a full stack trace
40             # including any sub-exceptions
41             # (see below for examples of
42             # this output format)
43             $@->toString(2);
44         }
45
46         # you can also declare inline exceptions
47         use Class::Throwable qw(My::App::Exception::IllegalOperation);
48
49         # set their global verbosity as well
50         # with the class method
51         My::App::Exception::IllegalOperation->setVerbosity(2);
52
53         eval {
54             throw My::App::Exception::IllegalOperation "Bad, real bad";
55         };
56
57         # can also declare subclasses of Class::Throwable
58         # in other files, then when you import them, you
59         # can set their verbosity
60         use My::Sub::Class::In::A::Separate::File (VERBOSE => 1);
61
62         throw My::Sub::Class::In::A::Separate::File "This exception will use a verbosity of 1";
63
64         # you can even create exceptions, then throw them later
65         my $e = Class::Throwable->new("Things have gone bad, but I need to do something first", $@);
66
67         # do something else ...
68
69         # then throw the exception we created earlier
70         throw $e
71

DESCRIPTION

73       This module implements a minimal lightweight exception object. It is
74       meant to be a compromise between more basic solutions like Carp which
75       can only print information and cannot handle exception objects, and
76       more more complex solutions like Exception::Class which can be used to
77       define complex inline exceptions and has a number of module
78       dependencies.
79
80   Inline Exceptions
81       You can easily create new exception classes inline by passing them with
82       the "use" statment like this:
83
84         use Class::Throwable ('My::InlineException', 'My::Other::InlineException');
85
86       This is a quick and easy way to define arbitrary exception classes
87       without the need to manually create separate files or packages for
88       them. However, it should be noted that subclasses of Class::Throwable
89       cannot be used to define inline exceptions. If you attempt to do this,
90       an exception will be thrown.
91
92   Exception Verbosity
93       Class::Throwable offers a number of different types of diagnostic
94       outputs to suit your needs. Most of this is controlled through the
95       verbosity levels. If the verbosity level is set to 0 or below, an empty
96       string is returned. If the value is set to 1, then the exception's
97       message is returned. If the value is set to 2 or above, a full stack
98       trace along with full stack traces for all sub-exceptions are returned
99       in the format shown in "stackTraceToString". The default verbosity
100       setting is 1.
101
102       There are a number of ways in which you can set the verbosity of the
103       exceptions produced by Class::Throwable. The simplest way is as the
104       argument to the "toString" method. Using this method will override any
105       other settings you may have, and insure that the output of this method
106       is as you ask it to be.
107
108         $@->toString(2);
109
110       However, to use this style properly, this requires that you test the
111       value of $@ to be sure it is a Class::Throwable object. In some cases,
112       this may not be an issue, while in others, it makes more sense to set
113       verbosity on a wider scale.
114
115       For instance, if you define inline exceptions, then the simplest way to
116       set a verbostity level for a particular inline exception is through the
117       class method "setVerbosity".
118
119         use Class::Throwable qw(My::InlineException);
120
121         My::InlineException->setVerbosity(2);
122
123       This means that unless the "toString" verbosity argument overrides it,
124       all My::InlineException exceptions will use a verbosity setting of 2.
125       This method means that you can easily "print" the value of $@ and then
126       any My::InlineException exceptions will be automatically stringified
127       with a verbosity level of 2. This can simplify exception catching by
128       reducing the need to inspect the value of $@.
129
130       If you defined your exceptions as subclasses of Class::Throwable and
131       stored them in separate files, then another means of setting the
132       verbosity level is to assign it in the "use" statement.
133
134         use My::SeparateFileSubClass::Exception (VERBOSE => 2);
135
136       This has the same effect as the "setVerbosity" class method, in fact,
137       there is nothing to stop you from using the "setVerbosity" class method
138       in this case if you like. This method can also be used on
139       Class::Throwable itself, however, this does not set the verbosity level
140       for all subclasses, only for Class::Throwable exceptions.
141
142       There is one last method which can be used. This method has the widest
143       scope of all the methods. The variable
144       $Class::Throwable::DEFAULT_VERBOSITY can be set. Setting this value
145       will take effect if, 1) there is no value passed to the "toString"
146       method and 2) no verbosity level has been set for the particular class,
147       either through "setVerbosity" or the "use" statement.
148
149   Module exception retro-fitting
150       It is possible to retrofit a module to use Class::Throwable exceptions
151       if you want to. Basically this will allow modules which "die" with
152       either strings or some other value, to throw Class::Throwable based
153       exceptions. This feature is relatively new and should be considered to
154       be experimental, any feedback on it is greatly appreciated.
155
156       NOTE: It is important to do module retrofitting at the earliest
157       possible moment (preferrably before the module you are retrofitting is
158       compiled), as it will override "die" within a specified package.
159
160       Other than all this, retrofitting is quite simple. Here is a basic
161       example:
162
163         use Class::Throwable retrofit => 'My::Class';
164
165       Now anytime "die" is called within My::Class the calls will get
166       converted to a Class::Throwable instance. You can also control how
167       exceptions are converted like so:
168
169         use Class::Throwable retrofit => 'My::Class' => sub { My::Exception->throw(@_) };
170
171       Now anytime "die" is called within My::Class the calls will get
172       converted to a My::Exception instance instead. Or a slightly more
173       complex examples like this:
174
175         use Class::Throwable retrofit => (
176                       'My::Class' => sub {
177                           My::IllegalOperation->throw(@_) if $_[0] =~ /^Illegal Operation/;
178                           My::Exception->throw(@_);
179                       });
180
181       Now anytime "die" is called within My::Class the calls will get
182       converted to a My::Exception instance unless the exception matches the
183       reg-exp, in which case an My::IllegalOperation exception is thrown.
184
185       There are a couple of points to be made regarding this functionality.
186       First, it will add another stack frame to your exceptions (the retrofit
187       routine basically). This is probably avoidable, but as this is still
188       experimental I wanted to keep things somewhat simple. And second, if
189       you supply a custom "die" handler, you should be sure that it will
190       "die" somewhere within that routine. If you do not, you may have many
191       un-intended consequences.
192

METHODS

194   Constructor
195       throw ($message, $sub_exception)
196           The most common way to construct an exception object is to "throw"
197           it. This method will construct the exception object, collect all
198           the information from the call stack and then "die".
199
200           The optional $message argument can be used to pass custom
201           information along with the exception object. Commonly this will be
202           a string, but this module makes no attempt to enforce that it be
203           anything other than a scalar, so more complex references or objects
204           can be used. If no $message is passed in, a default one will be
205           constructed for you.
206
207           The second optional argument, $sub_exception, can be used to retain
208           information about an exception which has been caught but might not
209           be appropriate to be re-thrown and is better wrapped within a new
210           exception object. While this argument will commonly be another
211           Class::Throwable object, that fact is not enforced so you can pass
212           in normal string based perl exceptions as well.
213
214           If this method is called as an instance method on an exception
215           object pre-built with "new", only then is the stack trace
216           information populated and the exception is then passed to "die".
217
218       new ($message, $sub_exception)
219           This is an alternate means of creating an exception object, it is
220           much like "throw", except that it does not collect stack trace
221           information or "die". It stores the $message and $sub_exception
222           values, and then returns the exception instance, to be possibly
223           thrown later on.
224
225   Class Methods
226       setVerbosity ($verbosity)
227           This is a class method, if it is called with an instance, and
228           exception will be thrown. This class method can be used to set the
229           verbosity level for a particular class. See the section "Exception
230           Verbosity" above for more details.
231
232   Accessors
233       getMessage
234           This allows access to the message in the exception, to allow more
235           granular exception reporting.
236
237       getStackTrace
238           This returns the raw stack trace information as an array of arrays.
239           There are 10 values returned by "caller" ($package, $filename,
240           $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require,
241           $hints, $bitmask) we do not bother to capture the last two as they
242           are subject to change and meant for internal use, all others are
243           retained in the order returned by "caller".
244
245       hasSubException
246           The returns true (1) if this exception has a sub-exception, and
247           false (0) otherwise.
248
249       getSubException
250           This allows access to the stored sub-exception.
251
252   Output Methods
253       This object overloads the stringification operator, and will call the
254       "toString" method to perform that stringification.
255
256       toString ($verbosity)
257           This will print out the exception object's information at a
258           variable level of verbosity which is specified be the optional
259           argument $verbosity. See the section "Exception Verbosity" above
260           for more details.
261
262       stringValue
263           This will return the normal perl stringified value of the object
264           without going through the "toString" method.
265
266       stackTraceToString
267           This method is used to print the stack trace information, the stack
268           trace is presented in the following format:
269
270               |--[ main::foo called in my_script.pl line 12 ]
271               |--[ main::bar called in my_script.pl line 14 ]
272               |--[ main::baz called in my_script.pl line 16 ]
273

EXAMPLE OUTPUT

275       Given the following code:
276
277         {
278           package Foo;
279           sub foo { eval { Bar::bar() }; throw Class::Throwable "Foo!!", $@ }
280
281           package Bar;
282           sub bar { eval { Baz::baz() }; throw Class::Throwable "Bar!!", $@ }
283
284           package Baz;
285           sub baz { throw Class::Throwable "Baz!!" }
286         }
287
288         eval { Foo::foo() };
289         print $@->toString($verbosity) if $@;
290
291       If you were to print the exception with verbosity of 0, you would get
292       no output at all. This mode can be used to suppress exception output if
293       needed. If you were to print the exception with verbosity of 1, you
294       would get this output.
295
296         Class::Throwable : Foo!!
297
298       If you were to print the exception with verbosity of 2, you would get
299       this output.
300
301         Class::Throwable : Foo!!
302           |--[ Foo::foo called in test.pl line 26 ]
303           |--[ main::(eval) called in test.pl line 26 ]
304           + Class::Throwable : Bar!!
305               |--[ Bar::bar called in test.pl line 19 ]
306               |--[ Foo::(eval) called in test.pl line 19 ]
307               |--[ Foo::foo called in test.pl line 26 ]
308               |--[ main::(eval) called in test.pl line 26 ]
309               + Class::Throwable : Baz!!
310                   |--[ Baz::baz called in test.pl line 21 ]
311                   |--[ Bar::(eval) called in test.pl line 21 ]
312                   |--[ Bar::bar called in test.pl line 19 ]
313                   |--[ Foo::(eval) called in test.pl line 19 ]
314                   |--[ Foo::foo called in test.pl line 26 ]
315                   |--[ main::(eval) called in test.pl line 26 ]
316

BUGS

318       None that I am aware of. Of course, if you find a bug, let me know, and
319       I will be sure to fix it. This is based on code which has been heavily
320       used in production sites for over 2 years now without incident.
321

CODE COVERAGE

323       I use Devel::Cover to test the code coverage of my tests, below is the
324       Devel::Cover report on this module test suite.
325
326        ---------------------------- ------ ------ ------ ------ ------ ------ ------
327        File                           stmt branch   cond    sub    pod   time  total
328        ---------------------------- ------ ------ ------ ------ ------ ------ ------
329        Class/Throwable.pm            100.0   98.0   63.6  100.0  100.0  100.0   95.7
330        ---------------------------- ------ ------ ------ ------ ------ ------ ------
331        Total                         100.0   98.0   63.6  100.0  100.0  100.0   95.7
332        ---------------------------- ------ ------ ------ ------ ------ ------ ------
333

SEE ALSO

335       There are a number of ways to do exceptions with perl, I was not really
336       satisifed with the way anyone else did them, so I created this module.
337       However, if you find this module unsatisfactory, you may want to check
338       these out.
339
340       Throwable
341           Throwable is a role for classes that are meant to be thrown as
342           exceptions to standard program flow.
343
344       Exception::Class
345           This in one of the more common exception classes out there. It does
346           an excellent job with it's default behavior, and allows a number of
347           complex options which can likely serve any needs you might have. My
348           reasoning for not using this module is that I felt these extra
349           options made things more complex than they needed to be, it also
350           introduced a number of dependencies. I am not saying this module is
351           bloated at all, but that for me it was far more than I have found I
352           needed. If you have heavy duty exception needs, this is your
353           module.
354
355       Error
356           This is the classic perl exception module, complete with a
357           try/catch mechanism. This module has a lot of bad karma associated
358           with it because of the obscure nested closure memory leak that
359           try/catch has. I never really liked the way its exception object
360           Error::Simple did things either.
361
362       Exception
363           This module I have never really experimented with, so take my
364           opinion with a large grain of salt. My problem with this module was
365           always that it seemed to want to do too much. It attempts to make
366           perl into a language with real exceptions, but messing with %SIG
367           handlers and other such things. This can be dangerous territory
368           sometimes, and for me, far more than my needs.
369

AUTHOR

371       stevan little, <stevan@iinteractive.com>
372
374       Copyright 2004 by Infinity Interactive, Inc.
375
376       <http://www.iinteractive.com>
377
378       This library is free software; you can redistribute it and/or modify it
379       under the same terms as Perl itself.
380
381
382
383perl v5.32.1                      2021-01-27               Class::Throwable(3)
Impressum