comparison variant_effect_predictor/Bio/EnsEMBL/Utils/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 =head1 LICENSE
2
3 Copyright (c) 1999-2012 The European Bioinformatics Institute and
4 Genome Research Limited. All rights reserved.
5
6 This software is distributed under a modified Apache license.
7 For license details, please see
8
9 http://www.ensembl.org/info/about/code_licence.html
10
11 =head1 CONTACT
12
13 Please email comments or questions to the public Ensembl
14 developers list at <dev@ensembl.org>.
15
16 Questions may also be sent to the Ensembl help desk at
17 <helpdesk@ensembl.org>.
18
19 =cut
20
21 =head1 NAME
22
23 Bio::EnsEMBL::Utils::Exception - Utility functions for error handling
24
25 =head1 SYNOPSIS
26
27 use Bio::EnsEMBL::Utils::Exception
28 qw(throw warning deprecate verbose try catch);
29
30 or to get all methods just
31
32 use Bio::EnsEMBL::Utils::Exception;
33
34 eval { throw("this is an exception with a stack trace") };
35 if ($@) {
36 print "Caught exception:\n$@";
37 }
38
39 # Or you can us the try/catch confortable syntax instead to deal with
40 # throw or die. Don't forget the ";" after the catch block. With
41 # this syntax, the original $@ is in $_ in the catch subroutine.
42
43 try {
44 throw("this is an exception with a stack trace");
45 }
46 catch { print "Caught exception:\n$_" };
47
48 # silence warnings
49 verbose('OFF');
50
51 warning('this is a silent warning');
52
53 #show deprecated and warning messages but not info
54 verbose('DEPRECATE');
55
56 warning('this is a warning');
57
58 # show all messages
59 verbose('ALL');
60
61 info('this is an informational message');
62
63 sub my_sub { deprecate('use other_sub() instead') }
64
65 verbose('EXCEPTION');
66 info( 'This is a high priority info message.', 1000 );
67
68 =head1 DESCRIPTION
69
70 This is derived from the Bio::Root module in BioPerl. Some formatting
71 has been changed and the deprecate function has been added. Most
72 notably the object methods are now static class methods that can be
73 called without inheriting from Bio::Root or Bio::EnsEMBL::Root. This is
74 especially useful for throwing exceptions with stack traces outside of a
75 blessed context.
76
77 The originaly implementations of these methods were by Steve Chervitz
78 and refactored by Ewan Birney.
79
80 It is recommended that these functions be used instead of inheriting
81 unnecessarily from the Bio::EnsEMBL::Root or Bio::Root object. The
82 functions exported by this package provide a set of useful error
83 handling methods.
84
85 =head1 METHODS
86
87 =cut
88
89 package Bio::EnsEMBL::Utils::Exception;
90
91 use strict;
92 use warnings;
93
94 use Bio::EnsEMBL::ApiVersion;
95
96 use Exporter;
97
98 use vars qw(@ISA @EXPORT);
99
100 @ISA = qw(Exporter);
101 @EXPORT = qw(throw warning stack_trace_dump
102 stack_trace verbose deprecate info try catch);
103
104 my $VERBOSITY = 3000;
105 my $DEFAULT_INFO = 4000;
106 my $DEFAULT_DEPRECATE = 3000;
107 my $DEFAULT_WARNING = 2000;
108 my $DEFAULT_EXCEPTION = 1000;
109
110
111 =head2 throw
112
113 Arg [1] : string $msg
114 Arg [2] : (optional) int $level
115 override the default level of exception throwing
116 Example : use Bio::EnsEMBL::Utils::Exception qw(throw);
117 throw('We have a problem');
118 Description: Throws an exception which if not caught by an eval will
119 provide a stack trace to STDERR and die. If the verbosity level
120 is lower than the level of the throw, then no error message is
121 displayed but the program will still die (unless the exception
122 is caught).
123 Returntype : none
124 Exceptions : thrown every time
125 Caller : generally on error
126
127 =cut
128
129 sub throw {
130 my $string = shift;
131
132 # For backwards compatibility with Bio::EnsEMBL::Root::throw: Allow
133 # to be called as an object method as well as class method. Root
134 # function now deprecated so call will have the string instead.
135
136 $string = shift if ( ref($string) ); # Skip object if one provided.
137 $string = shift if ( $string eq "Bio::EnsEMBL::Utils::Exception" );
138
139 my $level = shift;
140 $level = $DEFAULT_EXCEPTION if ( !defined($level) );
141
142 if ( $VERBOSITY < $level ) {
143 die("\n"); # still die, but silently
144 }
145
146 my $std = stack_trace_dump(3);
147
148 my $out = sprintf(
149 "\n" .
150 "-------------------- EXCEPTION --------------------\n" .
151 "MSG: %s\n" .
152 "%s" .
153 "Date (localtime) = %s\n" .
154 "Ensembl API version = %s\n" .
155 "---------------------------------------------------\n",
156 $string, $std, scalar( localtime() ), software_version() );
157
158 die($out);
159 } ## end sub throw
160
161
162
163 =head2 warning
164
165 Arg [1] : string warning(message);
166 Arg [2] : (optional) int level
167 Override the default level of this warning changning the level
168 of verbosity at which it is displayed.
169 Example : use Bio::EnsEMBL::Utils::Exception qw(warning)
170 warning('This is a warning');
171 Description: If the verbosity level is higher or equal to the level of this
172 warning then a warning message is printed to STDERR. If the
173 verbosity lower then nothing is done. Under the default
174 levels of warning and verbosity warnings will be displayed.
175 Returntype : none
176 Exceptions : warning every time
177 Caller : general
178
179 =cut
180
181 sub warning {
182 my $string = shift;
183
184 # See throw() for this:
185 $string = shift if ( ref($string) ); # Skip object if one provided.
186 $string = shift if ( $string eq "Bio::EnsEMBL::Utils::Exception" );
187
188 my $level = shift;
189 $level = $DEFAULT_WARNING if ( !defined($level) );
190
191 return if ( $VERBOSITY < $level );
192
193 my @caller = caller;
194 my $line = $caller[2] || '';
195
196 # Use only two sub-dirs for brevity when reporting the file name.
197 my $file;
198 my @path = split( /\//, $caller[1] );
199 $file = pop(@path);
200 my $i = 0;
201 while ( @path && $i < 2 ) {
202 $i++;
203 $file = pop(@path) . "/$file";
204 }
205
206 @caller = caller(1);
207 my $caller_line;
208 my $caller_file;
209 $i = 0;
210 if (@caller) {
211 @path = split( /\//, $caller[1] );
212 $caller_line = $caller[2];
213 $caller_file = pop(@path);
214 while ( @path && $i < 2 ) {
215 $i++;
216 $caller_file = pop(@path) . "/$caller_file";
217 }
218 }
219
220 my $out =
221 sprintf( "\n" .
222 "-------------------- WARNING ----------------------\n" .
223 "MSG: %s\n" .
224 "FILE: %s LINE: %d\n",
225 $string, $file, $line );
226
227 if ( defined($caller_file) ) {
228 $out .= sprintf( "CALLED BY: %s LINE: %d\n", $caller_file,
229 $caller_line );
230 }
231 $out .= sprintf(
232 "Date (localtime) = %s\n" .
233 "Ensembl API version = %s\n" .
234 "---------------------------------------------------\n",
235 scalar( localtime() ), software_version() );
236
237 warn($out);
238
239 } ## end sub warning
240
241
242
243 =head2 info
244
245 Arg [1] : string $string
246 The message to be displayed
247 Arg [2] : (optional) int $level
248 Override the default level of this message so it is displayed at
249 a different level of verbosity than it normally would be.
250 Example : use Bio::EnsEMBL::Utils::Exception qw(verbose info)
251 Description: This prints an info message to STDERR if verbosity is higher
252 than the level of the message. By default info messages are not
253 displayed.
254 Returntype : none
255 Exceptions : none
256 Caller : general
257
258 =cut
259
260 sub info {
261 my $string = shift;
262 $string = shift if($string eq "Bio::EnsEMBL::Utils::Exception");
263 my $level = shift;
264
265 $level = $DEFAULT_INFO if(!defined($level));
266
267 return if($VERBOSITY < $level);
268
269 print STDERR "INFO: $string\n";
270 }
271
272
273
274 =head2 verbose
275
276 Arg [1] : (optional) int
277 Example : use Bio::EnsEMBL::Utils::Exception qw(verbose warning);
278 #turn warnings and everything more important on (e.g. exception)
279 verbose('WARNING');
280 warning("Warning displayed");
281 info("This won't be displayed");
282 deprecate("This won't be diplayed");
283
284 #turn exception messages on
285 verbose('EXCEPTION');
286 warning("This won't do anything");
287 throw("Die with a message");
288
289 #turn everying off
290 verbose('OFF'); #same as verbose(0);
291 warning("This won't do anything");
292 throw("Die silently without a message");
293
294 #turn on all messages
295 verbose('ALL');
296 info("All messages are now displayed");
297
298 if(verbose() > 3000) {
299 print "Verbosity is pretty high";
300 }
301
302 Description: Gets/Sets verbosity level which defines which messages are
303 to be displayed. An integer value may be passed or one of the
304 following strings:
305 'OFF' (= 0)
306 'EXCEPTION' (= 1000)
307 'WARNING' (= 2000)
308 'DEPRECATE' (= 3000)
309 'INFO' (= 4000)
310 'ALL' (= 1000000)
311
312 Returntype : int
313 Exceptions : none
314 Caller : general
315
316 =cut
317
318
319 sub verbose {
320 if(@_) {
321 my $verbosity = shift;
322 $verbosity = shift if($verbosity eq "Bio::EnsEMBL::Utils::Exception");
323 if($verbosity =~ /\d+/) { #check if verbosity is an integer
324 $VERBOSITY = $verbosity;
325 } else {
326 $verbosity = uc($verbosity);
327 if($verbosity eq 'OFF' || $verbosity eq 'NOTHING' ||
328 $verbosity eq 'NONE') {
329 $VERBOSITY = 0;
330 } elsif($verbosity eq 'EXCEPTION' || $verbosity eq 'THROW') {
331 $VERBOSITY = $DEFAULT_EXCEPTION;
332 } elsif($verbosity eq 'WARNING' || $verbosity eq 'WARN') {
333 $VERBOSITY = $DEFAULT_WARNING;
334 } elsif($verbosity eq 'DEPRECATE' || $verbosity eq 'DEPRECATED') {
335 $VERBOSITY = $DEFAULT_DEPRECATE;
336 } elsif($verbosity eq 'INFO') {
337 $VERBOSITY = $DEFAULT_INFO;
338 } elsif($verbosity eq 'ON' || $verbosity eq 'ALL') {
339 $VERBOSITY = 1e6;
340 } else {
341 $VERBOSITY = $DEFAULT_WARNING;
342 warning("Unknown level of verbosity: $verbosity");
343 }
344 }
345 }
346
347 return $VERBOSITY;
348 }
349
350
351
352 =head2 stack_trace_dump
353
354 Arg [1] : (optional) int $levels
355 The number of levels to ignore from the top of the stack when
356 creating the dump. This is useful when this is called internally
357 from a warning or throw function when the immediate caller and
358 stack_trace_dump function calls are themselves uninteresting.
359 Example : use Bio::EnsEMBL::Utils::Exception qw(stack_trace_dump);
360 print STDERR stack_trace_dump();
361 Description: Returns a stack trace formatted as a string
362 Returntype : string
363 Exceptions : none
364 Caller : general, throw, warning
365
366 =cut
367
368 sub stack_trace_dump{
369 my @stack = stack_trace();
370
371 my $levels = 2; #default is 2 levels so stack_trace_dump call is not present
372 $levels = shift if(@_);
373 $levels = shift if($levels eq "Bio::EnsEMBL::Utils::Exception");
374 $levels = 1 if($levels < 1);
375
376 while($levels) {
377 $levels--;
378 shift @stack;
379 }
380
381 my $out;
382 my ($module,$function,$file,$position);
383
384
385 foreach my $stack ( @stack) {
386 ($module,$file,$position,$function) = @{$stack};
387 $out .= "STACK $function $file:$position\n";
388 }
389
390 return $out;
391 }
392
393
394
395 =head2 stack_trace
396
397 Arg [1] : none
398 Example : use Bio::EnsEMBL::Utils::Exception qw(stack_trace)
399 Description: Gives an array to a reference of arrays with stack trace info
400 each coming from the caller(stack_number) call
401 Returntype : array of listrefs of strings
402 Exceptions : none
403 Caller : general, stack_trace_dump()
404
405 =cut
406
407 sub stack_trace {
408 my $i = 0;
409 my @out;
410 my $prev;
411 while ( my @call = caller($i++)) {
412
413 # major annoyance that caller puts caller context as
414 # function name. Hence some monkeying around...
415 $prev->[3] = $call[3];
416 push(@out,$prev);
417 $prev = \@call;
418 }
419 $prev->[3] = 'toplevel';
420 push(@out,$prev);
421 return @out;
422 }
423
424
425 =head2 deprecate
426
427 Arg [1] : string $mesg
428 A message describing why a method is deprecated
429 Example : use Bio::EnsEMBL::Utils::Exception qw(deprecate)
430 sub old_sub {
431 deprecate('Please use new_sub() instead');
432 }
433 Description: Prints a warning to STDERR that the method which called
434 deprecate() is deprecated. Also prints the line number and
435 file from which the deprecated method was called. Deprecated
436 warnings only appear once for each location the method was
437 called from. No message is displayed if the level of verbosity
438 is lower than the level of the warning.
439 Returntype : none
440 Exceptions : warning every time
441 Caller : deprecated methods
442
443 =cut
444
445 my %DEPRECATED;
446
447 sub deprecate {
448 my $mesg = shift;
449 $mesg = shift if($mesg eq "Bio::EnsEMBL::Utils::Exception"); #skip object if one provided
450
451 my $level = shift;
452
453 $level = $DEFAULT_DEPRECATE if(!defined($level));
454
455 return if($VERBOSITY < $level);
456
457 my @caller = caller(1);
458 my $subname = $caller[3] ;
459 my $line = $caller[2];
460
461 #use only 2 subdirs for brevity when reporting the filename
462 my $file;
463 my @path = $caller[1];
464 $file = pop(@path);
465 my $i = 0;
466 while(@path && $i < 2) {
467 $i++;
468 $file .= pop(@path);
469 }
470
471 #keep track of who called this method so that the warning is only displayed
472 #once per deprecated call
473 return if $DEPRECATED{"$line:$file:$subname"};
474
475 if ( $VERBOSITY > -1 ) {
476 print STDERR
477 "\n------------------ DEPRECATED ---------------------\n"
478 . "Deprecated method call in file $file line $line.\n"
479 . "Method $subname is deprecated.\n"
480 . "$mesg\n"
481 . "Ensembl API version = "
482 . software_version() . "\n"
483 . "---------------------------------------------------\n";
484 }
485
486 $DEPRECATED{"$line:$file:$subname"} = 1;
487 }
488
489 =head2 try/catch
490
491 Arg [1] : anonymous subroutine
492 the block to be tried
493 Arg [2] : return value of the catch function
494 Example : use Bio::EnsEMBL::Utils::Exception qw(throw try catch)
495 The syntax is:
496 try { block1 } catch { block2 };
497 { block1 } is the 1st argument
498 catch { block2 } is the 2nd argument
499 e.g.
500 try {
501 throw("this is an exception with a stack trace");
502 } catch {
503 print "Caught exception:\n$_";
504 };
505 In block2, $_ is assigned the value of the first
506 throw or die statement executed in block 1.
507
508 Description: Replaces the classical syntax
509 eval { block1 };
510 if ($@) { block2 }
511 by a more confortable one.
512 In the try/catch syntax, the original $@ is in $_ in the catch subroutine.
513 This try/catch implementation is a copy and paste from
514 "Programming Perl" 3rd Edition, July 2000, by L.Wall, T. Christiansen
515 & J. Orwant. p227, and is only possible because of subroutine prototypes.
516 Returntype : depend on what is implemented the try or catch block
517 Exceptions : none
518 Caller : general
519
520 =cut
521
522 sub try (&$) {
523 my ($try, $catch) = @_;
524 eval { &$try };
525 if ($@) {
526 chop $@;
527 local $_ = $@;
528 &$catch;
529 }
530 }
531
532 sub catch (&) {
533 shift;
534 }
535
536 1;