Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Root/Exception.pm @ 0:1f6dce3d34e0
Uploaded
author | mahtabm |
---|---|
date | Thu, 11 Apr 2013 02:01:53 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1f6dce3d34e0 |
---|---|
1 #----------------------------------------------------------------- | |
2 # $Id: Exception.pm,v 1.14 2002/06/29 00:42:17 sac Exp $ | |
3 # | |
4 # BioPerl module Bio::Root::Exception | |
5 # | |
6 # Cared for by Steve Chervitz <sac@bioperl.org> | |
7 # | |
8 # You may distribute this module under the same terms as perl itself | |
9 #----------------------------------------------------------------- | |
10 | |
11 =head1 NAME | |
12 | |
13 Bio::Root::Exception - Generic exception objects for Bioperl | |
14 | |
15 =head1 SYNOPSIS | |
16 | |
17 =head2 Throwing exceptions using B<Error::throw()>: | |
18 | |
19 use Bio::Root::Exception; | |
20 use Error; | |
21 | |
22 # Set Error::Debug to include stack trace data in the error messages | |
23 $Error::Debug = 1; | |
24 | |
25 $file = shift; | |
26 open (IN, $file) || | |
27 throw Bio::Root::FileOpenException ( "Can't open file $file for reading", $!); | |
28 | |
29 =head2 Throwing exceptions using B<Bio::Root::Root::throw()>: | |
30 | |
31 # Here we have an object that ISA Bio::Root::Root, so it inherits throw(). | |
32 | |
33 open (IN, $file) || | |
34 $object->throw(-class => 'Bio::Root::FileOpenException', | |
35 -text => "Can't open file $file for reading", | |
36 -value => $!); | |
37 | |
38 =head2 Catching and handling exceptions using B<Error::try()>: | |
39 | |
40 use Bio::Root::Exception; | |
41 use Error qw(:try); | |
42 | |
43 # Note that we need to import the 'try' tag from Error.pm | |
44 | |
45 # Set Error::Debug to include stack trace data in the error messages | |
46 $Error::Debug = 1; | |
47 | |
48 $file = shift; | |
49 try { | |
50 open (IN, $file) || | |
51 throw Bio::Root::FileOpenException ( "Can't open file $file for reading", $!); | |
52 } | |
53 catch Bio::Root::FileOpenException with { | |
54 my $err = shift; | |
55 print STDERR "Using default input file: $default_file\n"; | |
56 open (IN, $default_file) || die "Can't open $default_file"; | |
57 } | |
58 otherwise { | |
59 my $err = shift; | |
60 print STDERR "An unexpected exception occurred: \n$err"; | |
61 | |
62 # By placing an the error object reference within double quotes, | |
63 # you're invoking its stringify() method. | |
64 } | |
65 finally { | |
66 # Any code that you want to execute regardless of whether or not | |
67 # an exception occurred. | |
68 }; | |
69 # the ending semicolon is essential! | |
70 | |
71 | |
72 =head2 Defining a new Exception type as a subclass of Bio::Root::Exception: | |
73 | |
74 @Bio::TestException::ISA = qw( Bio::Root::Exception ); | |
75 | |
76 | |
77 =head1 DESCRIPTION | |
78 | |
79 =head2 Exceptions defined in B<Bio::Root::Exception> | |
80 | |
81 These are generic exceptions for typical problem situations that could arise | |
82 in any module or script. | |
83 | |
84 =over 8 | |
85 | |
86 =item Bio::Root::Exception() | |
87 | |
88 =item Bio::Root::NotImplemented() | |
89 | |
90 =item Bio::Root::IOException() | |
91 | |
92 =item Bio::Root::FileOpenException() | |
93 | |
94 =item Bio::Root::SystemException() | |
95 | |
96 =item Bio::Root::BadParameter() | |
97 | |
98 =item Bio::Root::OutOfRange() | |
99 | |
100 =item Bio::Root::NoSuchThing() | |
101 | |
102 =back | |
103 | |
104 Using defined exception classes like these is a good idea because it | |
105 indicates the basic nature of what went wrong in a convenient, | |
106 computable way. | |
107 | |
108 If there is a type of exception that you want to throw | |
109 that is not covered by the classes listed above, it is easy to define | |
110 a new one that fits your needs. Just write a line like the following | |
111 in your module or script where you want to use it (or put it somewhere | |
112 that is accessible to your code): | |
113 | |
114 @NoCanDoException::ISA = qw( Bio::Root::Exception ); | |
115 | |
116 All of the exceptions defined in this module inherit from a common | |
117 base class exception, Bio::Root::Exception. This allows a user to | |
118 write a handler for all Bioperl-derived exceptions as follows: | |
119 | |
120 use Bio::Whatever; | |
121 use Error qw(:try); | |
122 | |
123 try { | |
124 # some code that depends on Bioperl | |
125 } | |
126 catch Bio::Root::Exception with { | |
127 my $err = shift; | |
128 print "A Bioperl exception occurred:\n$err\n"; | |
129 }; | |
130 | |
131 So if you do create your own exceptions, just be sure they inherit | |
132 from Bio::Root::Exception directly, or indirectly by inheriting from a | |
133 Bio::Root::Exception subclass. | |
134 | |
135 The exceptions in Bio::Root::Exception are extensions of Graham Barr's | |
136 B<Error.pm> module available from CPAN. Despite this dependency, the | |
137 Bio::Root::Exception module does not explicitly C<require Error>. | |
138 This permits Bio::Root::Exception to be loaded even when | |
139 Error.pm is not available. | |
140 | |
141 =head2 Throwing exceptions within Bioperl modules | |
142 | |
143 Error.pm is not part of the Bioperl distibution, and may not be | |
144 present within any given perl installation. So, when you want to | |
145 throw an exception in a Bioperl module, the safe way to throw it | |
146 is to use B<Bio::Root::Root::throw()> which can use Error.pm | |
147 when it's available. See documentation in Bio::Root::Root for details. | |
148 | |
149 =head1 SEE ALSO | |
150 | |
151 See the C<examples/exceptions> directory of the Bioperl distribution for | |
152 working demo code. | |
153 | |
154 B<Bio::Root::Root::throw()> for information about throwing | |
155 Bio::Root::Exception-based exceptions. | |
156 | |
157 B<Error.pm> (available from CPAN, author: GBARR) | |
158 | |
159 Error.pm is helping to guide the design of exception handling in Perl 6. | |
160 See these RFC's: | |
161 | |
162 http://dev.perl.org/rfc/63.pod | |
163 | |
164 http://dev.perl.org/rfc/88.pod | |
165 | |
166 | |
167 =head1 AUTHOR | |
168 | |
169 Steve Chervitz E<lt>sac@bioperl.orgE<gt> | |
170 | |
171 =head1 COPYRIGHT | |
172 | |
173 Copyright (c) 2001 Steve Chervitz. All Rights Reserved. | |
174 | |
175 This library is free software; you can redistribute it and/or modify | |
176 it under the same terms as Perl itself. | |
177 | |
178 =head1 DISCLAIMER | |
179 | |
180 This software is provided "as is" without warranty of any kind. | |
181 | |
182 =head1 EXCEPTIONS | |
183 | |
184 =cut | |
185 | |
186 # Define some generic exceptions.' | |
187 | |
188 package Bio::Root::Exception; | |
189 | |
190 use strict; | |
191 | |
192 my $debug = $Error::Debug; # Prevents the "used only once" warning. | |
193 my $DEFAULT_VALUE = "__DUMMY__"; # Permits eval{} based handlers to work | |
194 | |
195 =head2 B<Bio::Root::Exception> | |
196 | |
197 Purpose : A generic base class for all BioPerl exceptions. | |
198 By including a "catch Bio::Root::Exception" block, you | |
199 should be able to trap all BioPerl exceptions. | |
200 Example : throw Bio::Root::Exception("A generic exception", $!); | |
201 | |
202 =cut | |
203 | |
204 #--------------------------------------------------------- | |
205 @Bio::Root::Exception::ISA = qw( Error ); | |
206 #--------------------------------------------------------- | |
207 | |
208 =head2 Methods defined by Bio::Root::Exception | |
209 | |
210 =over 4 | |
211 | |
212 =item B< new() > | |
213 | |
214 Purpose : Guarantees that -value is set properly before | |
215 calling Error::new(). | |
216 | |
217 Arguments: key-value style arguments same as for Error::new() | |
218 | |
219 You can also specify plain arguments as ($message, $value) | |
220 where $value is optional. | |
221 | |
222 -value, if defined, must be non-zero and not an empty string | |
223 in order for eval{}-based exception handlers to work. | |
224 These require that if($@) evaluates to true, which will not | |
225 be the case if the Error has no value (Error overloads | |
226 numeric operations to the Error::value() method). | |
227 | |
228 It is OK to create Bio::Root::Exception objects without | |
229 specifing -value. In this case, an invisible dummy value is used. | |
230 | |
231 If you happen to specify a -value of zero (0), it will | |
232 be replaced by the string "The number zero (0)". | |
233 | |
234 If you happen to specify a -value of empty string (""), it will | |
235 be replaced by the string "An empty string ("")". | |
236 | |
237 =cut | |
238 | |
239 sub new { | |
240 my ($class, @args) = @_; | |
241 my ($value, %params); | |
242 if( @args % 2 == 0 && $args[0] =~ /^-/) { | |
243 %params = @args; | |
244 $value = $params{'-value'}; | |
245 } | |
246 else { | |
247 $params{-text} = $args[0]; | |
248 $value = $args[1]; | |
249 } | |
250 | |
251 if( defined $value and not $value) { | |
252 $value = "The number zero (0)" if $value == 0; | |
253 $value = "An empty string (\"\")" if $value eq ""; | |
254 } | |
255 else { | |
256 $value ||= $DEFAULT_VALUE; | |
257 } | |
258 $params{-value} = $value; | |
259 | |
260 my $self = $class->SUPER::new( %params ); | |
261 return $self; | |
262 } | |
263 | |
264 =item pretty_format() | |
265 | |
266 Purpose : Get a nicely formatted string containing information about the | |
267 exception. Format is similar to that produced by | |
268 Bio::Root::Root::throw(), with the addition of the name of | |
269 the exception class in the EXCEPTION line and some other | |
270 data available via the Error object. | |
271 Example : print $error->pretty_format; | |
272 | |
273 =cut | |
274 | |
275 sub pretty_format { | |
276 my $self = shift; | |
277 my $msg = $self->text; | |
278 my $stack = ''; | |
279 if( $Error::Debug ) { | |
280 $stack = $self->_reformat_stacktrace(); | |
281 } | |
282 my $value_string = $self->value ne $DEFAULT_VALUE ? "VALUE: ".$self->value."\n" : ""; | |
283 my $class = ref($self); | |
284 | |
285 my $title = "------------- EXCEPTION: $class -------------"; | |
286 my $footer = "\n" . '-' x CORE::length($title); | |
287 my $out = "\n$title\n" . | |
288 "MSG: $msg\n". $value_string. $stack. $footer . "\n"; | |
289 return $out; | |
290 } | |
291 | |
292 | |
293 # Reformatting of the stack performed by _reformat_stacktrace: | |
294 # 1. Shift the file:line data in line i to line i+1. | |
295 # 2. change xxx::__ANON__() to "try{} block" | |
296 # 3. skip the "require" and "Error::subs::try" stack entries (boring) | |
297 # This means that the first line in the stack won't have any file:line data | |
298 # But this isn't a big issue since it's for a Bio::Root::-based method | |
299 # that doesn't vary from exception to exception. | |
300 | |
301 sub _reformat_stacktrace { | |
302 my $self = shift; | |
303 my $msg = $self->text; | |
304 my $stack = $self->stacktrace(); | |
305 $stack =~ s/\Q$msg//; | |
306 my @stack = split( /\n/, $stack); | |
307 my @new_stack = (); | |
308 my ($method, $file, $linenum, $prev_file, $prev_linenum); | |
309 my $stack_count = 0; | |
310 foreach my $i( 0..$#stack ) { | |
311 # print "STACK-ORIG: $stack[$i]\n"; | |
312 if( ($stack[$i] =~ /^\s*([^(]+)\s*\(.*\) called at (\S+) line (\d+)/) || | |
313 ($stack[$i] =~ /^\s*(require 0) called at (\S+) line (\d+)/)) { | |
314 ($method, $file, $linenum) = ($1, $2, $3); | |
315 $stack_count++; | |
316 } | |
317 else{ | |
318 next; | |
319 } | |
320 if( $stack_count == 1 ) { | |
321 push @new_stack, "STACK: $method"; | |
322 ($prev_file, $prev_linenum) = ($file, $linenum); | |
323 next; | |
324 } | |
325 | |
326 if( $method =~ /__ANON__/ ) { | |
327 $method = "try{} block"; | |
328 } | |
329 if( ($method =~ /^require/ and $file =~ /Error\.pm/ ) || | |
330 ($method =~ /^Error::subs::try/ ) ) { | |
331 last; | |
332 } | |
333 push @new_stack, "STACK: $method $prev_file:$prev_linenum"; | |
334 ($prev_file, $prev_linenum) = ($file, $linenum); | |
335 } | |
336 push @new_stack, "STACK: $prev_file:$prev_linenum"; | |
337 | |
338 return join "\n", @new_stack; | |
339 } | |
340 | |
341 =item B< stringify() > | |
342 | |
343 Purpose : Overrides Error::stringify() to call pretty_format(). | |
344 This is called automatically when an exception object | |
345 is placed between double quotes. | |
346 Example : catch Bio::Root::Exception with { | |
347 my $error = shift; | |
348 print "$error"; | |
349 } | |
350 | |
351 See Also: L<pretty_format()|pretty_format> | |
352 | |
353 =cut | |
354 | |
355 sub stringify { | |
356 my ($self, @args) = @_; | |
357 return $self->pretty_format( @args ); | |
358 } | |
359 | |
360 | |
361 | |
362 =back | |
363 | |
364 =head1 Subclasses of Bio::Root::Exception | |
365 | |
366 | |
367 =head2 B<Bio::Root::NotImplemented> | |
368 | |
369 Purpose : Indicates that a method has not been implemented. | |
370 Example : throw Bio::Root::NotImplemented( | |
371 -text => "Method \"foo\" not implemented in module FooBar.", | |
372 -value => "foo" ); | |
373 | |
374 =cut | |
375 | |
376 #--------------------------------------------------------- | |
377 @Bio::Root::NotImplemented::ISA = qw( Bio::Root::Exception ); | |
378 #--------------------------------------------------------- | |
379 | |
380 =head2 B<Bio::Root::IOException> | |
381 | |
382 Purpose : Indicates that some input/output-related trouble has occurred. | |
383 Example : throw Bio::Root::IOException( | |
384 -text => "Can't save data to file $file.", | |
385 -value => $! ); | |
386 | |
387 =cut | |
388 | |
389 #--------------------------------------------------------- | |
390 @Bio::Root::IOException::ISA = qw( Bio::Root::Exception ); | |
391 #--------------------------------------------------------- | |
392 | |
393 | |
394 =head2 B<Bio::Root::FileOpenException> | |
395 | |
396 Purpose : Indicates that a file could not be opened. | |
397 Example : throw Bio::Root::FileOpenException( | |
398 -text => "Can't open file $file for reading.", | |
399 -value => $! ); | |
400 | |
401 =cut | |
402 | |
403 #--------------------------------------------------------- | |
404 @Bio::Root::FileOpenException::ISA = qw( Bio::Root::IOException ); | |
405 #--------------------------------------------------------- | |
406 | |
407 | |
408 =head2 B<Bio::Root::SystemException> | |
409 | |
410 Purpose : Indicates that a system call failed. | |
411 Example : unlink($file) or throw Bio::Root::SystemException( | |
412 -text => "Can't unlink file $file.", | |
413 -value => $! ); | |
414 | |
415 =cut | |
416 | |
417 #--------------------------------------------------------- | |
418 @Bio::Root::SystemException::ISA = qw( Bio::Root::Exception ); | |
419 #--------------------------------------------------------- | |
420 | |
421 | |
422 =head2 B<Bio::Root::BadParameter> | |
423 | |
424 Purpose : Indicates that one or more parameters supplied to a method | |
425 are invalid, unspecified, or conflicting. | |
426 Example : throw Bio::Root::BadParameter( | |
427 -text => "Required parameter \"-foo\" was not specified", | |
428 -value => "-foo" ); | |
429 | |
430 =cut | |
431 | |
432 #--------------------------------------------------------- | |
433 @Bio::Root::BadParameter::ISA = qw( Bio::Root::Exception ); | |
434 #--------------------------------------------------------- | |
435 | |
436 | |
437 =head2 B<Bio::Root::OutOfRange> | |
438 | |
439 Purpose : Indicates that a specified (start,end) range or | |
440 an index to an array is outside the permitted range. | |
441 Example : throw Bio::Root::OutOfRange( | |
442 -text => "Start coordinate ($start) cannot be less than zero.", | |
443 -value => $start ); | |
444 | |
445 =cut | |
446 | |
447 #--------------------------------------------------------- | |
448 @Bio::Root::OutOfRange::ISA = qw( Bio::Root::Exception ); | |
449 #--------------------------------------------------------- | |
450 | |
451 | |
452 =head2 B<Bio::Root::NoSuchThing> | |
453 | |
454 Purpose : Indicates that a requested thing cannot be located | |
455 and therefore could possibly be bogus. | |
456 Example : throw Bio::Root::NoSuchThing( | |
457 -text => "Accession M000001 could not be found.", | |
458 -value => "M000001" ); | |
459 | |
460 =cut | |
461 | |
462 #--------------------------------------------------------- | |
463 @Bio::Root::NoSuchThing::ISA = qw( Bio::Root::Exception ); | |
464 #--------------------------------------------------------- | |
465 | |
466 | |
467 1; | |
468 |