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

NAME

6       Exception::Class - A module that allows you to declare real exception
7       classes in Perl
8

SYNOPSIS

10         use Exception::Class
11             ( 'MyException',
12
13               'AnotherException' =>
14               { isa => 'MyException' },
15
16               'YetAnotherException' =>
17               { isa => 'AnotherException',
18                 description => 'These exceptions are related to IPC' },
19
20               'ExceptionWithFields' =>
21               { isa => 'YetAnotherException',
22                 fields => [ 'grandiosity', 'quixotic' ],
23                 alias => 'throw_fields',
24               },
25             );
26
27         # try
28         eval { MyException->throw( error => 'I feel funny.' ) };
29
30         my $e;
31         # catch
32         if ( $e = Exception::Class->caught('MyException') )
33         {
34            warn $e->error, "\n", $e->trace->as_string, "\n";
35            warn join ' ',  $e->euid, $e->egid, $e->uid, $e->gid, $e->pid, $e->time;
36
37            exit;
38         }
39         elsif ( $e = Exception::Class->caught('ExceptionWithFields') )
40         {
41            $e->quixotic ? do_something_wacky() : do_something_sane();
42         }
43         else
44         {
45            $e = Exception::Class->caught();
46            ref $e ? $e->rethrow : die $e;
47         }
48
49         # use an alias - without parens subroutine name is checked at
50         # compile time
51         throw_fields error => "No strawberry", grandiosity => "quite a bit";
52

DESCRIPTION

54       Exception::Class allows you to declare exception hierarchies in your
55       modules in a "Java-esque" manner.
56
57       It features a simple interface allowing programmers to 'declare' excep‐
58       tion classes at compile time.  It also has a base exception class,
59       Exception::Class::Base, that can be easily extended.
60
61       It is designed to make structured exception handling simpler and better
62       by encouraging people to use hierarchies of exceptions in their appli‐
63       cations, as opposed to a single catch-all exception class.
64
65       This module does not implement any try/catch syntax.  Please see the
66       "OTHER EXCEPTION MODULES (try/catch syntax)" section for more informa‐
67       tion on how to get this syntax.
68

DECLARING EXCEPTION CLASSES

70       Importing "Exception::Class" allows you to automagically create "Excep‐
71       tion::Class::Base" subclasses.  You can also create subclasses via the
72       traditional means of defining your own subclass with @ISA.  These two
73       methods may be easily combined, so that you could subclass an exception
74       class defined via the automagic import, if you desired this.
75
76       The syntax for the magic declarations is as follows:
77
78       'MANDATORY CLASS NAME' => \%optional_hashref
79
80       The hashref may contain the following options:
81
82       * isa
83           This is the class's parent class.  If this isn't provided then the
84           class name in $Exception::Class::BASE_EXC_CLASS is assumed to be
85           the parent (see below).
86
87           This parameter lets you create arbitrarily deep class hierarchies.
88           This can be any other "Exception::Class::Base" subclass in your
89           declaration or a subclass loaded from a module.
90
91           To change the default exception class you will need to change the
92           value of $Exception::Class::BASE_EXC_CLASS before calling
93           "import()".  To do this simply do something like this:
94
95           BEGIN { $Exception::Class::BASE_EXC_CLASS = 'SomeExceptionClass'; }
96
97           If anyone can come up with a more elegant way to do this please let
98           me know.
99
100           CAVEAT: If you want to automagically subclass an "Excep‐
101           tion::Class::Base" subclass loaded from a file, then you must com‐
102           pile the class (via use or require or some other magic) before you
103           import "Exception::Class" or you'll get a compile time error.
104
105       * fields
106           This allows you to define additional attributes for your exception
107           class.  Any field you define can be passed to the "throw()" or
108           "new()" methods as additional parameters for the constructor.  In
109           addition, your exception object will have an accessor method for
110           the fields you define.
111
112           This parameter can be either a scalar (for a single field) or an
113           array reference if you need to define multiple fields.
114
115           Fields will be inherited by subclasses.
116
117       * alias
118           Specifying an alias causes this class to create a subroutine of the
119           specified name in the caller's namespace.  Calling this subroutine
120           is equivalent to calling "<class>->throw(@_)" for the given excep‐
121           tion class.
122
123           Besides convenience, using aliases also allows for additional com‐
124           pile time checking.  If the alias is called without parentheses, as
125           in "throw_fields "an error occurred"", then Perl checks for the
126           existence of the "throw_fields()" subroutine at compile time.  If
127           instead you do "ExceptionWithFields->throw(...)", then Perl checks
128           the class name at runtime, meaning that typos may sneak through.
129
130       * description
131           Each exception class has a description method that returns a fixed
132           string.  This should describe the exception class (as opposed to
133           any particular exception object).  This may be useful for debugging
134           if you start catching exceptions you weren't expecting (particu‐
135           larly if someone forgot to document them) and you don't understand
136           the error messages.
137
138       The "Exception::Class" magic attempts to detect circular class hierar‐
139       chies and will die if it finds one.  It also detects missing links in a
140       chain, for example if you declare Bar to be a subclass of Foo and never
141       declare Foo.
142

Catching Exceptions

144       "Exception::Class" provides some syntactic sugar for catching excep‐
145       tions in a safe manner:
146
147        eval { ... }
148
149        if ( my $e = Exception::Class->caught('My::Error') )
150        {
151            cleanup();
152            do_something_with_exception($e);
153        }
154
155       The "caught()" method takes a class name and returns an exception
156       object if the last thrown exception is of the given class, or a sub‐
157       class of that class.  If it is not given any arguments, it simply
158       returns $@.
159
160       You should always make a copy of the exception object, rather than
161       using $@ directly.  This is necessary because if your "cleanup()" func‐
162       tion uses "eval", or calls something which uses it, then $@ is over‐
163       written.  Copying the exception preserves it for the call to "do_some‐
164       thing_with_exception()".
165
166       Exception objects also provide a caught method so you can write:
167
168        if ( my $e = My::Error->caught() )
169        {
170            cleanup();
171            do_something_with_exception($e);
172        }
173
174       Uncatchable Exceptions
175
176       Internally, the "caught()" method will call "isa()" on the exception
177       object.  You could make an exception "uncatchable" by overriding
178       "isa()" in that class like this:
179
180        package Exception::Uncatchable;
181
182        sub isa { shift->rethrow }
183
184       Of course, this only works if you always call "Excep‐
185       tion::Class->caught()" after an "eval".
186

Exception::Class::Base CLASS METHODS

188       * Trace($boolean)
189           Each "Exception::Class::Base" subclass can be set individually to
190           include a a stracktrace when the "as_string" method is called.  The
191           default is to not include a stacktrace.  Calling this method with a
192           value changes this behavior.  It always returns the current value
193           (after any change is applied).
194
195           This value is inherited by any subclasses.  However, if this value
196           is set for a subclass, it will thereafter be independent of the
197           value in "Exception::Class::Base".
198
199           This is a class method, not an object method.
200
201       * NoRefs($boolean)
202           When a "Devel::StackTrace" object is created, it walks through the
203           stack and stores the arguments which were passed to each subroutine
204           on the stack.  If any of these arguments are references, then that
205           means that the "Devel::StackTrace" ends up increasing the refcount
206           of these references, delaying their destruction.
207
208           Since "Exception::Class::Base" uses "Devel::StackTrace" internally,
209           this method provides a way to tell "Devel::StackTrace" not to store
210           these references.  Instead, "Devel::StackTrace" replaces references
211           with their stringified representation.
212
213           This method defaults to true.  As with "Trace()", it is inherited
214           by subclasses but setting it in a subclass makes it independent
215           thereafter.
216
217       * RespectOverload($boolean)
218           When a "Devel::StackTrace" object stringifies, by default it
219           ignores stringification overloading on any objects being dealt
220           with.
221
222           Since "Exception::Class::Base" uses "Devel::StackTrace" internally,
223           this method provides a way to tell "Devel::StackTrace" to respect
224           overloading.
225
226           This method defaults to false.  As with "Trace()", it is inherited
227           by subclasses but setting it in a subclass makes it independent
228           thereafter.
229
230       * Fields
231           This method returns the extra fields defined for the given class,
232           as an array.
233
234       * throw( $message )
235       * throw( message => $message )
236       * throw( error => $error )
237           This method creates a new object with the given error message.  If
238           no error message is given, $! is used.  It then die's with this
239           object as its argument.
240
241           This method also takes a "show_trace" parameter which indicates
242           whether or not the particular exception object being created should
243           show a stacktrace when its "as_string()" method is called.  This
244           overrides the value of "Trace()" for this class if it is given.
245
246           The frames included in the trace can be controlled by the
247           "ignore_class" and "ignore_package" parameters. These are passed
248           directly to Devel::Stacktrace's constructor. See "Devel::Stack‐
249           trace" for more details.
250
251           If only a single value is given to the constructor it is assumed to
252           be the message parameter.
253
254           Additional keys corresponding to the fields defined for the partic‐
255           ular exception subclass will also be accepted.
256
257       * new
258           This method takes the same parameters as "throw()", but instead of
259           dying simply returns a new exception object.
260
261           This method is always called when constructing a new exception
262           object via the "throw()" method.
263
264       * description
265           Returns the description for the given "Exception::Class::Base" sub‐
266           class.  The "Exception::Class::Base" class's description is
267           "Generic exception" (this may change in the future).  This is also
268           an object method.
269

Exception::Class::Base OBJECT METHODS

271       * rethrow
272           Simply dies with the object as its sole argument.  It's just syn‐
273           tactic sugar.  This does not change any of the object's attribute
274           values.  However, it will cause "caller()" to report the die as
275           coming from within the "Exception::Class::Base" class rather than
276           where rethrow was called.
277
278           Of course, you always have access to the original stacktrace for
279           the exception object.
280
281       * message
282       * error
283           Returns the error/message associated with the exception.
284
285       * pid
286           Returns the pid at the time the exception was thrown.
287
288       * uid
289           Returns the real user id at the time the exception was thrown.
290
291       * gid
292           Returns the real group id at the time the exception was thrown.
293
294       * euid
295           Returns the effective user id at the time the exception was thrown.
296
297       * egid
298           Returns the effective group id at the time the exception was
299           thrown.
300
301       * time
302           Returns the time in seconds since the epoch at the time the excep‐
303           tion was thrown.
304
305       * package
306           Returns the package from which the exception was thrown.
307
308       * file
309           Returns the file within which the exception was thrown.
310
311       * line
312           Returns the line where the exception was thrown.
313
314       * trace
315           Returns the trace object associated with the object.
316
317       * show_trace($boolean)
318           This method can be used to set whether or not a strack trace is
319           included when the as_string method is called or the object is
320           stringified.
321
322       * as_string
323           Returns a string form of the error message (something like what
324           you'd expect from die).  If the class or object is set to show
325           traces then then the full trace is also included.  The result looks
326           like "Carp::confess()".
327
328       * full_message
329           Called by the "as_string()" method to get the message.  By default,
330           this is the same as calling the "message()" method, but may be
331           overridden by a subclass.  See below for details.
332

OVERLOADING

334       The "Exception::Class::Base" object is overloaded so that stringifica‐
335       tion produces a normal error message.  It just calls the as_string
336       method described above.  This means that you can just "print $@" after
337       an "eval" and not worry about whether or not its an actual object.  It
338       also means an application or module could do this:
339
340        $SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
341
342       and this would probably not break anything (unless someone was expect‐
343       ing a different type of exception object from "die()").
344

OVERRIDING THE as_string METHOD

346       By default, the "as_string()" method simply returns the value "message"
347       or "error" param plus a stack trace, if the class's "Trace()" method
348       returns a true value or "show_trace" was set when creating the excep‐
349       tion.
350
351       However, once you add new fields to a subclass, you may want to include
352       those fields in the stringified error.
353
354       Inside the "as_string()" method, the message (non-stack trace) portion
355       of the error is generated by calling the "full_message()" method.  This
356       can be easily overridden.  For example:
357
358         sub full_message
359         {
360             my $self = shift;
361
362             my $msg = $self->message;
363
364             $msg .= " and foo was " . $self->foo;
365
366             return $msg;
367         }
368

USAGE RECOMMENDATION

370       If you're creating a complex system that throws lots of different types
371       of exceptions, consider putting all the exception declarations in one
372       place.  For an app called Foo you might make a "Foo::Exceptions" module
373       and use that in all your code.  This module could just contain the code
374       to make "Exception::Class" do its automagic class creation.  Doing this
375       allows you to more easily see what exceptions you have, and makes it
376       easier to keep track of them.
377
378       This might look something like this:
379
380         package Foo::Bar::Exceptions;
381
382         use Exception::Class ( Foo::Bar::Exception::Senses =>
383                               { description => 'sense-related exception' },
384
385                                Foo::Bar::Exception::Smell =>
386                                { isa => 'Foo::Bar::Exception::Senses',
387                                  fields => 'odor',
388                                  description => 'stinky!' },
389
390                                Foo::Bar::Exception::Taste =>
391                                { isa => 'Foo::Bar::Exception::Senses',
392                                  fields => [ 'taste', 'bitterness' ],
393                                  description => 'like, gag me with a spoon!' },
394
395                                ... );
396
397       You may want to create a real module to subclass "Excep‐
398       tion::Class::Base" as well, particularly if you want your exceptions to
399       have more methods.
400
401       Subclassing Exception::Class::Base
402
403       As part of your usage of "Exception::Class", you may want to create
404       your own base exception class which subclasses "Excep‐
405       tion::Class::Base".  You should feel free to subclass any of the meth‐
406       ods documented above.  For example, you may want to subclass "new()" to
407       add additional information to your exception objects.
408

Exception::Class FUNCTIONS

410       The "Exception::Class" method offers one function, "Classes()", which
411       is not exported.  This method returns a list of the classes that have
412       been created by calling the "Exception::Class" import() method.  Note
413       that this is all the subclasses that have been created, so it may
414       include subclasses created by things like CPAN modules, etc.  Also note
415       that if you simply define a subclass via the normal Perl method of set‐
416       ting @ISA or "use base", then your subclass will not be included.
417

OTHER EXCEPTION MODULES (try/catch syntax)

419       If you are interested in adding try/catch/finally syntactic sugar to
420       your code then I recommend you check out U. Arun Kumar's "Error.pm"
421       module, which implements this syntax.  It also includes its own base
422       exception class, "Error::Simple".
423
424       If you would prefer to use the "Exception::Class::Base" class included
425       with this module, you'll have to add this to your code somewhere:
426
427         push @Exception::Class::Base::ISA, 'Error'
428             unless Exception::Class::Base->isa('Error');
429
430       It's a hack but apparently it works.
431

AUTHOR

433       Dave Rolsky, <autarch@urth.org>
434

SEE ALSO

436       Devel::StackTrace - used by this module to create stack traces
437
438       Error.pm - implements try/catch in Perl.  Also provides an exception
439       base class.
440
441       Test::Exception - a module that helps you test exception based code.
442
443       Numerous other modules/frameworks seem to have their own exception
444       classes (SPOPS and Template Toolkit, to name two) but none of these
445       seem to be designed for use outside of these packages.
446
447
448
449perl v5.8.8                       2006-01-14               Exception::Class(3)
Impressum