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