1Exception::Class(3) User Contributed Perl Documentation Exception::Class(3)
2
3
4
6 Exception::Class - A module that allows you to declare real exception
7 classes in Perl
8
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
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'
58 exception 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
63 applications, 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
67 information on how to get this syntax.
68
69 You will also want to look at the documentation for
70 Exception::Class::Base, which is the default base class for all
71 exception objects created by this module.
72
74 Importing "Exception::Class" allows you to automagically create
75 Exception::Class::Base subclasses. You can also create subclasses via
76 the traditional means of defining your own subclass with @ISA. These
77 two methods may be easily combined, so that you could subclass an
78 exception class defined via the automagic import, if you desired this.
79
80 The syntax for the magic declarations is as follows:
81
82 'MANDATORY CLASS NAME' => \%optional_hashref
83
84 The hashref may contain the following options:
85
86 · isa
87
88 This is the class's parent class. If this isn't provided then the
89 class name in $Exception::Class::BASE_EXC_CLASS is assumed to be
90 the parent (see below).
91
92 This parameter lets you create arbitrarily deep class hierarchies.
93 This can be any other Exception::Class::Base subclass in your
94 declaration or a subclass loaded from a module.
95
96 To change the default exception class you will need to change the
97 value of $Exception::Class::BASE_EXC_CLASS before calling
98 "import()". To do this simply do something like this:
99
100 BEGIN { $Exception::Class::BASE_EXC_CLASS = 'SomeExceptionClass'; }
101
102 If anyone can come up with a more elegant way to do this please let
103 me know.
104
105 CAVEAT: If you want to automagically subclass an
106 Exception::Class::Base subclass loaded from a file, then you must
107 compile the class (via use or require or some other magic) before
108 you import "Exception::Class" or you'll get a compile time error.
109
110 · fields
111
112 This allows you to define additional attributes for your exception
113 class. Any field you define can be passed to the "throw()" or
114 "new()" methods as additional parameters for the constructor. In
115 addition, your exception object will have an accessor method for
116 the fields you define.
117
118 This parameter can be either a scalar (for a single field) or an
119 array reference if you need to define multiple fields.
120
121 Fields will be inherited by subclasses.
122
123 · alias
124
125 Specifying an alias causes this class to create a subroutine of the
126 specified name in the caller's namespace. Calling this subroutine
127 is equivalent to calling "<class>->throw(@_)" for the given
128 exception class.
129
130 Besides convenience, using aliases also allows for additional
131 compile time checking. If the alias is called without parentheses,
132 as in "throw_fields "an error occurred"", then Perl checks for the
133 existence of the "throw_fields()" subroutine at compile time. If
134 instead you do "ExceptionWithFields->throw(...)", then Perl checks
135 the class name at runtime, meaning that typos may sneak through.
136
137 · description
138
139 Each exception class has a description method that returns a fixed
140 string. This should describe the exception class (as opposed to
141 any particular exception object). This may be useful for debugging
142 if you start catching exceptions you weren't expecting
143 (particularly if someone forgot to document them) and you don't
144 understand the error messages.
145
146 The "Exception::Class" magic attempts to detect circular class
147 hierarchies and will die if it finds one. It also detects missing
148 links in a chain, for example if you declare Bar to be a subclass of
149 Foo and never declare Foo.
150
152 "Exception::Class" provides some syntactic sugar for catching
153 exceptions in a safe manner:
154
155 eval { ... }
156
157 if ( my $e = Exception::Class->caught('My::Error') )
158 {
159 cleanup();
160 do_something_with_exception($e);
161 }
162
163 The "caught()" method takes a class name and returns an exception
164 object if the last thrown exception is of the given class, or a
165 subclass of that class. If it is not given any arguments, it simply
166 returns $@.
167
168 You should always make a copy of the exception object, rather than
169 using $@ directly. This is necessary because if your "cleanup()"
170 function uses "eval", or calls something which uses it, then $@ is
171 overwritten. Copying the exception preserves it for the call to
172 "do_something_with_exception()".
173
174 Exception objects also provide a caught method so you can write:
175
176 if ( my $e = My::Error->caught() )
177 {
178 cleanup();
179 do_something_with_exception($e);
180 }
181
182 Uncatchable Exceptions
183 Internally, the "caught()" method will call "isa()" on the exception
184 object. You could make an exception "uncatchable" by overriding
185 "isa()" in that class like this:
186
187 package Exception::Uncatchable;
188
189 sub isa { shift->rethrow }
190
191 Of course, this only works if you always call
192 "Exception::Class->caught()" after an "eval".
193
195 If you're creating a complex system that throws lots of different types
196 of exceptions, consider putting all the exception declarations in one
197 place. For an app called Foo you might make a "Foo::Exceptions" module
198 and use that in all your code. This module could just contain the code
199 to make "Exception::Class" do its automagic class creation. Doing this
200 allows you to more easily see what exceptions you have, and makes it
201 easier to keep track of them.
202
203 This might look something like this:
204
205 package Foo::Bar::Exceptions;
206
207 use Exception::Class ( Foo::Bar::Exception::Senses =>
208 { description => 'sense-related exception' },
209
210 Foo::Bar::Exception::Smell =>
211 { isa => 'Foo::Bar::Exception::Senses',
212 fields => 'odor',
213 description => 'stinky!' },
214
215 Foo::Bar::Exception::Taste =>
216 { isa => 'Foo::Bar::Exception::Senses',
217 fields => [ 'taste', 'bitterness' ],
218 description => 'like, gag me with a spoon!' },
219
220 ... );
221
222 You may want to create a real module to subclass Exception::Class::Base
223 as well, particularly if you want your exceptions to have more methods.
224
225 Subclassing Exception::Class::Base
226 As part of your usage of "Exception::Class", you may want to create
227 your own base exception class which subclasses Exception::Class::Base.
228 You should feel free to subclass any of the methods documented above.
229 For example, you may want to subclass "new()" to add additional
230 information to your exception objects.
231
233 The "Exception::Class" method offers one function, "Classes()", which
234 is not exported. This method returns a list of the classes that have
235 been created by calling the "Exception::Class" import() method. Note
236 that this is all the subclasses that have been created, so it may
237 include subclasses created by things like CPAN modules, etc. Also note
238 that if you simply define a subclass via the normal Perl method of
239 setting @ISA or "use base", then your subclass will not be included.
240
242 If you are interested in adding try/catch/finally syntactic sugar to
243 your code then I recommend you check out U. Arun Kumar's "Error.pm"
244 module, which implements this syntax. It also includes its own base
245 exception class, "Error::Simple".
246
247 If you would prefer to use the Exception::Class::Base class included
248 with this module, you'll have to add this to your code somewhere:
249
250 push @Exception::Class::Base::ISA, 'Error'
251 unless Exception::Class::Base->isa('Error');
252
253 It's a hack but apparently it works.
254
256 Please submit bugs to the CPAN RT system at
257 http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Exception%3A%3AClass or
258 via email at bug-exception-class@rt.cpan.org.
259
261 If you'd like to thank me for the work I've done on this module, please
262 consider making a "donation" to me via PayPal. I spend a lot of free
263 time creating free software, and would appreciate any support you'd
264 care to offer.
265
266 Please note that I am not suggesting that you must do this in order for
267 me to continue working on this particular software. I will continue to
268 do so, inasmuch as I have in the past, for as long as it interests me.
269
270 Similarly, a donation made in this way will probably not make me work
271 on this software much more, unless I get so many donations that I can
272 consider working on free software full time, which seems unlikely at
273 best.
274
275 To donate, log into PayPal and send money to autarch@urth.org or use
276 the button on this page:
277 <http://www.urth.org/~autarch/fs-donation.html>
278
280 Dave Rolsky, >autarch@urth.org<
281
283 Copyright (c) 2000-2009 David Rolsky. All rights reserved. This
284 program is free software; you can redistribute it and/or modify it
285 under the same terms as Perl itself.
286
287 The full text of the license can be found in the LICENSE file included
288 with this module.
289
290
291
292perl v5.10.1 2010-11-12 Exception::Class(3)