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

VERSION

10       version 1.37
11

SYNOPSIS

13         use Exception::Class (
14             'MyException',
15
16             'AnotherException' => { isa => 'MyException' },
17
18             'YetAnotherException' => {
19                 isa         => 'AnotherException',
20                 description => 'These exceptions are related to IPC'
21             },
22
23             'ExceptionWithFields' => {
24                 isa    => 'YetAnotherException',
25                 fields => [ 'grandiosity', 'quixotic' ],
26                 alias  => 'throw_fields',
27             },
28         );
29         use Scalar::Util qw( blessed );
30         use Try::Tiny;
31
32         try {
33             MyException->throw( error => 'I feel funny.' );
34         }
35         catch {
36             die $_ unless blessed $_ && $_->can('rethrow');
37
38             if ( $_->isa('Exception::Class') ) {
39                 warn $_->error, "\n", $_->trace->as_string, "\n";
40                 warn join ' ', $_->euid, $_->egid, $_->uid, $_->gid, $_->pid, $_->time;
41
42                 exit;
43             }
44             elsif ( $_->isa('ExceptionWithFields') ) {
45                 if ( $_->quixotic ) {
46                     handle_quixotic_exception();
47                 }
48                 else {
49                     handle_non_quixotic_exception();
50                 }
51             }
52             else {
53                 $_->rethrow;
54             }
55         };
56
57         # without Try::Tiny
58
59         eval { ... };
60         if ( my $e = Exception::Class->caught() ) { ... }
61
62         # use an alias - without parens subroutine name is checked at
63         # compile time
64         throw_fields error => "No strawberry", grandiosity => "quite a bit";
65

DESCRIPTION

67       RECOMMENDATION 1: If you are writing modern Perl code with Moose or Moo
68       I highly recommend using Throwable instead of this module.
69
70       RECOMMENDATION 2: Whether or not you use Throwable, you should use
71       Try::Tiny.
72
73       Exception::Class allows you to declare exception hierarchies in your
74       modules in a "Java-esque" manner.
75
76       It features a simple interface allowing programmers to 'declare'
77       exception classes at compile time.  It also has a base exception class,
78       Exception::Class::Base, that can be easily extended.
79
80       It is designed to make structured exception handling simpler and better
81       by encouraging people to use hierarchies of exceptions in their
82       applications, as opposed to a single catch-all exception class.
83
84       This module does not implement any try/catch syntax.  Please see the
85       "OTHER EXCEPTION MODULES (try/catch syntax)" section for more
86       information on how to get this syntax.
87
88       You will also want to look at the documentation for
89       Exception::Class::Base, which is the default base class for all
90       exception objects created by this module.
91

DECLARING EXCEPTION CLASSES

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

Try::Tiny

171       If you are interested in adding try/catch/finally syntactic sugar to
172       your code then I recommend you check out Try::Tiny. This is a great
173       module that helps you ignore some of the weirdness with "eval" and $@.
174       Here's an example of how the two modules work together:
175
176         use Exception::Class ( 'My::Exception' );
177         use Scalar::Util qw( blessed );
178         use Try::Tiny;
179
180         try {
181             might_throw();
182         }
183         catch {
184             if ( blessed $_ && $_->isa('My::Exception') ) {
185                 handle_it();
186             }
187             else {
188                 die $_;
189             }
190         };
191
192       Note that you cannot use "Exception::Class->caught()" with Try::Tiny.
193

Catching Exceptions Without Try::Tiny

195       "Exception::Class" provides some syntactic sugar for catching
196       exceptions in a safe manner:
197
198         eval {...};
199
200         if ( my $e = Exception::Class->caught('My::Error') ) {
201             cleanup();
202             do_something_with_exception($e);
203         }
204
205       The "caught()" method takes a class name and returns an exception
206       object if the last thrown exception is of the given class, or a
207       subclass of that class.  If it is not given any arguments, it simply
208       returns $@.
209
210       You should always make a copy of the exception object, rather than
211       using $@ directly.  This is necessary because if your "cleanup()"
212       function uses "eval", or calls something which uses it, then $@ is
213       overwritten.  Copying the exception preserves it for the call to
214       "do_something_with_exception()".
215
216       Exception objects also provide a caught method so you can write:
217
218         if ( my $e = My::Error->caught() ) {
219             cleanup();
220             do_something_with_exception($e);
221         }
222
223   Uncatchable Exceptions
224       Internally, the "caught()" method will call "isa()" on the exception
225       object.  You could make an exception "uncatchable" by overriding
226       "isa()" in that class like this:
227
228        package Exception::Uncatchable;
229
230        sub isa { shift->rethrow }
231
232       Of course, this only works if you always call
233       "Exception::Class->caught()" after an "eval".
234

USAGE RECOMMENDATION

236       If you're creating a complex system that throws lots of different types
237       of exceptions, consider putting all the exception declarations in one
238       place.  For an app called Foo you might make a "Foo::Exceptions" module
239       and use that in all your code.  This module could just contain the code
240       to make "Exception::Class" do its automagic class creation.  Doing this
241       allows you to more easily see what exceptions you have, and makes it
242       easier to keep track of them.
243
244       This might look something like this:
245
246         package Foo::Bar::Exceptions;
247
248         use Exception::Class (
249             Foo::Bar::Exception::Senses =>
250                 { description => 'sense-related exception' },
251
252             Foo::Bar::Exception::Smell => {
253                 isa         => 'Foo::Bar::Exception::Senses',
254                 fields      => 'odor',
255                 description => 'stinky!'
256             },
257
258             Foo::Bar::Exception::Taste => {
259                 isa         => 'Foo::Bar::Exception::Senses',
260                 fields      => [ 'taste', 'bitterness' ],
261                 description => 'like, gag me with a spoon!'
262             },
263
264             ...
265         );
266
267       You may want to create a real module to subclass Exception::Class::Base
268       as well, particularly if you want your exceptions to have more methods.
269
270   Subclassing Exception::Class::Base
271       As part of your usage of "Exception::Class", you may want to create
272       your own base exception class which subclasses Exception::Class::Base.
273       You should feel free to subclass any of the methods documented above.
274       For example, you may want to subclass "new()" to add additional
275       information to your exception objects.
276

Exception::Class FUNCTIONS

278       The "Exception::Class" method offers one function, "Classes()", which
279       is not exported.  This method returns a list of the classes that have
280       been created by calling the "Exception::Class" import() method.  Note
281       that this is all the subclasses that have been created, so it may
282       include subclasses created by things like CPAN modules, etc.  Also note
283       that if you simply define a subclass via the normal Perl method of
284       setting @ISA or "use base", then your subclass will not be included.
285

SUPPORT

287       Please submit bugs to the CPAN RT system at
288       http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Exception%3A%3AClass or
289       via email at bug-exception-class@rt.cpan.org.
290

DONATIONS

292       If you'd like to thank me for the work I've done on this module, please
293       consider making a "donation" to me via PayPal. I spend a lot of free
294       time creating free software, and would appreciate any support you'd
295       care to offer.
296
297       Please note that I am not suggesting that you must do this in order for
298       me to continue working on this particular software. I will continue to
299       do so, inasmuch as I have in the past, for as long as it interests me.
300
301       Similarly, a donation made in this way will probably not make me work
302       on this software much more, unless I get so many donations that I can
303       consider working on free software full time, which seems unlikely at
304       best.
305
306       To donate, log into PayPal and send money to autarch@urth.org or use
307       the button on this page:
308       <http://www.urth.org/~autarch/fs-donation.html>
309

AUTHOR

311       Dave Rolsky <autarch@urth.org>
312
314       This software is copyright (c) 2013 by Dave Rolsky.
315
316       This is free software; you can redistribute it and/or modify it under
317       the same terms as the Perl 5 programming language system itself.
318
319
320
321perl v5.16.3                      2013-02-24               Exception::Class(3)
Impressum