Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Root/Err.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 # PACKAGE : Bio::Root::Err.pm | |
3 # AUTHOR : Steve Chervitz (sac@bioperl.org) | |
4 # CREATED : 22 July 1996 | |
5 # REVISION: $Id: Err.pm,v 1.15 2002/10/22 07:38:37 lapp Exp $ | |
6 # STATUS : Alpha | |
7 # | |
8 # For documentation, run this module through pod2html | |
9 # (preferably from Perl v5.004 or better). | |
10 # | |
11 # Copyright (c) 1996-8 Steve Chervitz. All Rights Reserved. | |
12 # This module is free software; you can redistribute it and/or | |
13 # modify it under the same terms as Perl itself. | |
14 # Retain this notice and note any modifications made. | |
15 #----------------------------------------------------------------------------- | |
16 | |
17 package Bio::Root::Err; | |
18 use strict; | |
19 | |
20 use Bio::Root::Global qw(:devel $CGI); | |
21 use Bio::Root::Vector (); | |
22 use Bio::Root::Object;# qw(:std); | |
23 use Exporter (); | |
24 | |
25 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); | |
26 @ISA = qw( Bio::Root::Object Bio::Root::Vector Exporter ); | |
27 @EXPORT = qw(); | |
28 @EXPORT_OK = qw( %ERR_FIELDS @ERR_TYPES &format_stack_entry &throw &warning); | |
29 %EXPORT_TAGS = ( | |
30 data => [qw(%ERR_FIELDS @ERR_TYPES)], | |
31 std => [qw(&throw &warning)] | |
32 ); | |
33 | |
34 use vars qw($ID $VERSION); | |
35 $ID = 'Bio::Root::Err'; | |
36 $VERSION = 0.041; | |
37 | |
38 %Bio::Root::Err::ERR_FIELDS = (TYPE=>1, MSG=>1, NOTE=>1, CONTEXT=>1, | |
39 TECH=>1, STACK=>1 ); | |
40 | |
41 @Bio::Root::Err::ERR_TYPES = qw(WARNING EXCEPTION FATAL); | |
42 | |
43 | |
44 ## MAIN POD DOCUMENTATION: | |
45 | |
46 =head1 NAME | |
47 | |
48 Bio::Root::Err - Exception class for Perl 5 objects | |
49 | |
50 =head1 SYNOPSIS | |
51 | |
52 =head2 Object Creation | |
53 | |
54 B<Bio::Root::Object.pm> is a wrapper for Bio::Root::Err.pm objects so clients | |
55 do not have to create these objects directly. Please see | |
56 B<Bio::Root::Object::throw()> as well as L<_initialize>() | |
57 for a more complete treatment | |
58 of how to create Bio::Root::Err.pm objects. | |
59 | |
60 use Bio::Root::Err; | |
61 | |
62 $err = Bio::Root::Err->new(-MSG =>"Bad data: $data", | |
63 -STACK =>[\caller(0), \caller(1), ...], | |
64 ); | |
65 | |
66 | |
67 To use the L<throw>() method directly: | |
68 | |
69 use Bio::Root::Err (:std); | |
70 | |
71 throw( $object_ref, 'Error message', 'additional note', 'technical note'); | |
72 | |
73 The C<$object_ref> argument should be a reference to a Bio::Root::Object.pm. | |
74 | |
75 See also L<the USAGE section | USAGE>. | |
76 | |
77 =head1 INSTALLATION | |
78 | |
79 This module is included with the central Bioperl distribution: | |
80 | |
81 http://bio.perl.org/Core/Latest | |
82 ftp://bio.perl.org/pub/DIST | |
83 | |
84 Follow the installation instructions included in the INSTALL file. | |
85 | |
86 =head1 DESCRIPTION | |
87 | |
88 A Bio::Root::Err.pm object encapsulates data and methods that facilitate | |
89 working with errors and exceptional conditions that arise in Perl objects. | |
90 There are no biological semantics in this module, as one may suspect from its | |
91 location in the Bio:: hierarchy. The location of this module serves to | |
92 separate it from the namespaces of other Perl Error modules. It also makes it | |
93 convenient for use by Bio:: objects. | |
94 | |
95 The motivation for having an error object is to allow | |
96 Perl 5 objects to deal with errors or exceptional conditions that | |
97 can arise during their construction or manipulation. For example: | |
98 | |
99 (1) A complex object can break in many ways. | |
100 (2) Tracking errors within a set of nested objects can be difficult. | |
101 (3) The way an error is reported should be context-sensitive: | |
102 a web-user needs different information than does the | |
103 software engineer. | |
104 | |
105 Bio::Root::Err.pm, along with B<Bio::Root::Object.pm>, attempt to make such | |
106 problems tractable. Please see the L<Bio::Root::Object> documentation for more | |
107 about my error handling philosophy. | |
108 | |
109 A B<Bio::Root::Err.pm> object is an example of a Vector-Object: This module | |
110 inherits both from B<Bio::Root::Object.pm> and B<Bio::Root::Vector.pm>. This | |
111 permits a single Err object to exist within a linked list of Err objects OR | |
112 alone. See the L<Bio::Root::Vector> documentation for more about Vector-Objects. | |
113 | |
114 B<The API for this module is not complete since the module is under development.> | |
115 | |
116 =head2 Other Exception Strategies | |
117 | |
118 Exception handling with Perl 5 objects is currently not as evolved as one | |
119 would like. The error handling used by B<Bio::Root::Object.pm> and Bio::Root::Err.pm | |
120 relies on Perl's built-in error/exception handling with eval/die, | |
121 which is not very object-aware. What I've attempted to do with these | |
122 modules is to make eval/die more object-savvy, as well as make Perl 5 | |
123 objects more eval/die-savvy (but the current strategy is basically a hack). | |
124 | |
125 It would be great if Perl could throw an object reference with die(). | |
126 This would permit more intelligent and easy to write exception handlers. | |
127 For now the Err.pm object is reconstructed from the output of L<string>(). | |
128 | |
129 There are some other third-party Exception classes such as | |
130 Torsten Ekedahl's B<Experimental::Exception.pm> or Ken Steven's Throwable.pm or | |
131 Graham Barr's Error.pm (see L<Other Exception Modules>). These modules | |
132 attempt to introduce a traditional "try-catch-throw" exception handling mechanism | |
133 into Perl. Future version of my modules (and perhaps Perl itself) may utilize one | |
134 of these. | |
135 | |
136 =head1 USAGE | |
137 | |
138 A demo script that illustrates working with Bio::Root::Err objects is | |
139 examples/root_object/error.pl. | |
140 | |
141 | |
142 =head1 DEPENDENCIES | |
143 | |
144 Bio::Root::Err.pm inherits from B<Bio::Root::Object.pm> and B<Bio::Root::Vector.pm>. | |
145 | |
146 | |
147 =head1 FEEDBACK | |
148 | |
149 =head2 Mailing Lists | |
150 | |
151 User feedback is an integral part of the evolution of this and other Bioperl modules. | |
152 Send your comments and suggestions preferably to one of the Bioperl mailing lists. | |
153 Your participation is much appreciated. | |
154 | |
155 bioperl-l@bioperl.org - General discussion | |
156 http://bioperl.org/MailList.shtml - About the mailing lists | |
157 | |
158 =head2 Reporting Bugs | |
159 | |
160 Report bugs to the Bioperl bug tracking system to help us keep track the bugs and | |
161 their resolution. Bug reports can be submitted via email or the web: | |
162 | |
163 bioperl-bugs@bio.perl.org | |
164 http://bugzilla.bioperl.org/ | |
165 | |
166 =head1 AUTHOR Steve Chervitz | |
167 | |
168 Email sac@bioperl.org | |
169 | |
170 See L<the FEEDBACK section | FEEDBACK> section for where to send bug reports and comments. | |
171 | |
172 =head1 VERSION | |
173 | |
174 Bio::Root::Err.pm, 0.041 | |
175 | |
176 | |
177 =head1 SEE ALSO | |
178 | |
179 Bio::Root::Object.pm - Core object | |
180 Bio::Root::Vector.pm - Vector object | |
181 Bio::Root::Global.pm - Manages global variables/constants | |
182 | |
183 http://bio.perl.org/Projects/modules.html - Online module documentation | |
184 http://bio.perl.org/ - Bioperl Project Homepage | |
185 | |
186 =head2 Other Exception Modules | |
187 | |
188 Experimental::Exception.pm - ftp://ftp.matematik.su.se/pub/teke/ | |
189 Error.pm - http://www.cpan.org/authors/id/GBARR/ | |
190 Throwable.pm - mailto:kstevens@globeandmail.ca | |
191 | |
192 http://genome-www.stanford.edu/perlOOP/exceptions.html | |
193 | |
194 =head1 ACKNOWLEDGEMENTS | |
195 | |
196 This module was developed under the auspices of the Saccharomyces Genome | |
197 Database: | |
198 http://genome-www.stanford.edu/Saccharomyces | |
199 | |
200 Other Bioperl developers contributed ideas including Ewan Birney, Ian Korf, | |
201 Chris Dagdigian, Georg Fuellen, and Steven Brenner. | |
202 | |
203 =head1 COPYRIGHT | |
204 | |
205 Copyright (c) 1996-8 Steve Chervitz. All Rights Reserved. | |
206 This module is free software; you can redistribute it and/or | |
207 modify it under the same terms as Perl itself. | |
208 | |
209 =head1 TODO | |
210 | |
211 =over 2 | |
212 | |
213 =item * Improve documentation. | |
214 | |
215 =item * Experiment with other Exception modules. | |
216 | |
217 =back | |
218 | |
219 =cut | |
220 | |
221 ## END MAIN POD DOCUMENTATION' | |
222 | |
223 =head1 APPENDIX | |
224 | |
225 Methods beginning with a leading underscore are considered private | |
226 and are intended for internal use by this module. They are | |
227 B<not> considered part of the public interface and are described here | |
228 for documentation purposes only. | |
229 | |
230 =cut | |
231 | |
232 | |
233 ######################################################## | |
234 # CONSTRUCTOR # | |
235 ######################################################## | |
236 | |
237 | |
238 =head2 _initialize | |
239 | |
240 Usage : n/a; automatically called by Bio::Root::Object::new() | |
241 Purpose : Initializes key Bio::Root::Err.pm data. | |
242 Returns : String (the -MAKE constructor option.) | |
243 Argument : Named parameters passed from new() | |
244 : (PARAMETER TAGS CAN BE UPPER OR LOWER CASE). | |
245 : -MSG => basic description of the exception. | |
246 : -NOTE => additional note to indicate cause of exception | |
247 : or provide information about how to fix/report it | |
248 : -TECH => addition note with technical information | |
249 : of interest to developer. | |
250 : -STACK => array reference containing caller() data | |
251 : -TYPE => string, one of @Bio::Root::Err::ERR_TYPES | |
252 : (default = exception). | |
253 : -CONTEXT => array reference | |
254 : -OBJ => Err object to be cloned. | |
255 | |
256 See Also : B<Bio::Root::Object::_set_err()> | |
257 | |
258 =cut | |
259 | |
260 #---------------- | |
261 sub _initialize { | |
262 #---------------- | |
263 my( $self, @param ) = @_; | |
264 | |
265 my $make = $self->Bio::Root::Object::_initialize( @param ); | |
266 | |
267 my( $msg, $note, $tech, $stack, $type, $context, $obj) = | |
268 $self->_rearrange([qw(MSG NOTE TECH STACK TYPE CONTEXT OBJ)], @param); | |
269 | |
270 ## NOTE: Don't eval {} the construction process for Err objects. | |
271 | |
272 if($make =~ /clone/i) { | |
273 $self->_set_clone($obj); | |
274 } else { | |
275 if(!$self->_build_from_string($msg, $note, $tech)) { | |
276 # print "Failed to rebuild: msg = $msg";<STDIN>; | |
277 $self->set('msg', $msg ); | |
278 $self->_set_type( $type ); | |
279 $self->_set_context($context); | |
280 $self->_set_list_data('note', $note ); | |
281 $self->_set_list_data('tech', $tech ); | |
282 $self->_set_list_data('stack', $stack ); | |
283 } | |
284 $self->set_display(); | |
285 } | |
286 | |
287 $DEBUG and do{ print STDERR "---> Initialized Err (${\ref($self)}).\n\n"; | |
288 # $self->print(); | |
289 }; | |
290 $make; | |
291 } | |
292 | |
293 ## | |
294 ## Destructor: Not needed currently. Perhaps if and when Vector is used by delegation. | |
295 ## | |
296 | |
297 ##################################################################################### | |
298 ## ACCESSORS ## | |
299 ##################################################################################### | |
300 | |
301 | |
302 | |
303 =head2 _set_clone | |
304 | |
305 Usage : n/a; internal method used by _initialize() | |
306 Purpose : Copy all Bio::Root::Err.pm data members into a new object reference. | |
307 Argument : object ref for object to be cloned. | |
308 Comments : Does not cloning the vector since this method is | |
309 : typically used to extract a single Err object from its vector. | |
310 | |
311 =cut | |
312 | |
313 #--------------- | |
314 sub _set_clone { | |
315 #--------------- | |
316 my($self, $obj) = @_; | |
317 | |
318 ref($obj) || throw($self, "Can't clone $ID object: Not an object ref ($obj)"); | |
319 | |
320 $self->{'_type'} = $obj->{'_type'}; | |
321 $self->{'_msg'} = $obj->{'_msg'}; | |
322 $self->{'_note'} = $obj->{'_note'}; | |
323 $self->{'_tech'} = $obj->{'_tech'}; | |
324 $self->{'_stack'} = $obj->{'_stack'}; | |
325 $self->{'_context'} = $obj->{'_context'}; | |
326 # $self->clone_vector($obj); | |
327 } | |
328 | |
329 | |
330 =head2 _build_from_string | |
331 | |
332 Usage : n/a; called by _initialize() | |
333 Purpose : Re-create an Err.pm object from a string containing Err data. | |
334 Returns : boolean, (was the Err.pm object rebuilt?) | |
335 Argument : message, note, tech passed from _initialize() | |
336 : The message is examined to see if it contains a stringified error. | |
337 | |
338 See Also : L<_initialize>(), L<string>(), L<_has_err>() | |
339 | |
340 =cut | |
341 | |
342 #---------------------- | |
343 sub _build_from_string { | |
344 #---------------------- | |
345 my ($self, $msg, $note, $tech) = @_; | |
346 my @list = split "\n", $msg; | |
347 my ($mode,$line); | |
348 my $rebuilt = 0; | |
349 | |
350 # print "$ID: Attempting to build from string: $msg";<STDIN>; | |
351 | |
352 MEMBER: | |
353 foreach $line (@list) { | |
354 if($line =~ /^-+$/) { last MEMBER; } | |
355 if($line =~ /^-+ (\w+) -+$/) { $self->{'_type'} = $1; $rebuilt = 1; next MEMBER; } | |
356 if($line =~ /^MSG: *(\w.*)/) { my $msg = $1; | |
357 if($self->_has_err($msg)) { | |
358 die "Duplicate error."; | |
359 } | |
360 $self->{'_msg'} = $msg; | |
361 $mode = 'msg'; | |
362 next MEMBER; } | |
363 if($line =~ /^CONTEXT: *(\w.*)/) { push @{$self->{'_context'}}, $1; $mode = 'context'; next MEMBER; } | |
364 if($line =~ /^NOTE: *(\w.*)/) { push @{$self->{'_note'}}, $1; $mode = 'note'; next MEMBER; } | |
365 if($line =~ /^TECH: *(\w.*)/) { push @{$self->{'_tech'}}, $1; $mode = 'tech'; next MEMBER; } | |
366 if($line =~ /^STACK:/) { $mode = 'stack'; next MEMBER; } | |
367 next MEMBER if !$mode; | |
368 SWITCH: { | |
369 local $_ = $mode; | |
370 m/msg/ && do{ $self->{'_msg'} .= "$line\n"; last SWITCH; }; | |
371 m/note/ && do{ push @{$self->{'_note'}}, $line; last SWITCH; }; | |
372 m/context/ && do{ push @{$self->{'_context'}}, $line; last SWITCH; }; | |
373 m/tech/ && do{ push @{$self->{'_tech'}}, $line; last SWITCH; }; | |
374 m/stack/ && do{ push @{$self->{'_stack'}}, $line; last SWITCH; }; | |
375 next MEMBER; | |
376 } | |
377 } | |
378 if($rebuilt) { | |
379 ## Optionally add additional notes. | |
380 $self->_set_list_data('note', $note) if defined $note; | |
381 $self->_set_list_data('tech', $tech) if defined $tech; | |
382 } | |
383 | |
384 $rebuilt; | |
385 } | |
386 | |
387 | |
388 =head2 _has_err | |
389 | |
390 Usage : n/a; internal method called by _build_from_string() | |
391 Purpose : Deterimine if an Err has already been set to prevent duplicate Errs. | |
392 Returns : boolean | |
393 | |
394 See Also : L<_build_from_string>() | |
395 | |
396 =cut | |
397 | |
398 #------------- | |
399 sub _has_err { | |
400 #------------- | |
401 my ($self, $msg) = @_; | |
402 | |
403 $msg =~ s/^\s+//; | |
404 $msg =~ s/\s+$//; | |
405 | |
406 my $err = $self->first; | |
407 my ($existing_msg); | |
408 do { | |
409 # print "checking err object $self\n"; | |
410 $existing_msg = $err->msg; | |
411 $existing_msg =~ s/^\s+//; | |
412 $existing_msg =~ s/\s+$//; | |
413 # print " msg: $existing_msg";<STDIN>; | |
414 return 1 if $existing_msg eq $msg; | |
415 | |
416 } while($err = $err->next); | |
417 | |
418 0; | |
419 } | |
420 | |
421 | |
422 =head2 _set_type | |
423 | |
424 Usage : n/a; internal method | |
425 Purpose : Sets the type of Err (warning, exception, fatal) | |
426 : Called by _initialize() | |
427 Argument : string | |
428 | |
429 =cut | |
430 | |
431 #---------------- | |
432 sub _set_type { | |
433 #---------------- | |
434 my( $self, $data ) = @_; | |
435 $data ||= 'EXCEPTION'; | |
436 | |
437 # printf "\n$ID: Setting type (%s) for err = %s\n", $data, $self->msg;<STDIN>; | |
438 | |
439 my (@type); | |
440 if( @type = grep /$data/i, @Bio::Root::Err::ERR_TYPES ) { | |
441 $self->{'_type'} = $type[0]; | |
442 } else { | |
443 $self->{'_type'} = 'EXCEPTION'; | |
444 } | |
445 | |
446 # print "type = $self->{'_type'} for $self";<STDIN>; | |
447 } | |
448 | |
449 | |
450 | |
451 =head2 _set_list_data | |
452 | |
453 Usage : n/a; internal method used by set(). | |
454 : $err->_set_list_data( $member, $data); | |
455 Purpose : For data members which are anonymous arrays: note, tech, stack, | |
456 : adds the given data to the list. | |
457 Arguments : $member = any of qw(note tech stack) | |
458 : $data = string | |
459 Comments : Splits $data on tab. Each item | |
460 : of the split is a new entry. | |
461 : To clobber the current data (unusual situation), you must first | |
462 : call set() with no data then call again with desired data. | |
463 | |
464 =cut | |
465 | |
466 #------------------- | |
467 sub _set_list_data { | |
468 #------------------- | |
469 my( $self, $member, $data ) = @_; | |
470 | |
471 # Sensitive to data member name changes. | |
472 $member = "_\l$member"; | |
473 | |
474 # $DEBUG && do {printf STDERR "\n$ID: Setting \"%s\" list data (%s)\n", $member, $data;<STDIN>; }; | |
475 | |
476 defined $self->{$member} and return $self->_add_list_data( $member, $data ); | |
477 | |
478 if( $data ) { | |
479 $self->{$member} = []; | |
480 if( $member =~ /stack/) { | |
481 foreach (@$data) { | |
482 push @{ $self->{$member}}, format_stack_entry(@$_); | |
483 } | |
484 } else { | |
485 my @entries = split "\t", $data; | |
486 foreach (@entries) { | |
487 next if /^$/; | |
488 # $DEBUG && do {print STDERR "adding $member: $_";<STDIN>;}; | |
489 push @{ $self->{$member}}, $_; | |
490 } | |
491 } | |
492 } else { | |
493 $self->{$member} = undef; | |
494 } | |
495 } | |
496 | |
497 | |
498 =head2 _set_context | |
499 | |
500 Usage : n/a; internal method used by set(). | |
501 Purpose : Sets the object containment context for the exception. | |
502 : (this is the hierarchy of objects in which the | |
503 : exception occurred.) | |
504 | |
505 =cut | |
506 | |
507 #------------------ | |
508 sub _set_context { | |
509 #------------------ | |
510 my($self, $aref) = @_; | |
511 | |
512 eval { | |
513 if (!ref $aref) { | |
514 # push @{$aref}, sprintf "object %s \"%s\"",ref($self->parent), $self->parent->name; | |
515 push @{$aref}, "UNKNOWN CONTEXT"; | |
516 } | |
517 }; | |
518 if($@) { push @{$aref}, 'undefined object'; } | |
519 | |
520 if($self->type eq 'EXCEPTION') { | |
521 $aref->[0] = "Exception thrown by \l$aref->[0]"; | |
522 } else { | |
523 $aref->[0] = "Error in \l$aref->[0]"; | |
524 } | |
525 | |
526 my $script = ($0 =~ /([\w\/\.]+)/, $1); | |
527 push @$aref, "SCRIPT: $script"; | |
528 | |
529 $self->{'_context'} = $aref; | |
530 | |
531 # print "$ID: _set_context():\n"; | |
532 # foreach(@$aref) { print " $_\n"; } | |
533 # <STDIN>; | |
534 } | |
535 | |
536 | |
537 | |
538 =head2 set | |
539 | |
540 Usage : $err->set( $member, $data ); | |
541 Purpose : General accessor for setting any Err.pm data member. | |
542 Example : $err->set('note', 'this is an additional note.'); | |
543 Returns : n/a | |
544 Argument : $member = string, any of qw(msg type note tech stack) | |
545 : $data = string | |
546 Throws : n/a | |
547 Comments : Note, tech, and stack items are appended to any existing | |
548 : notes, tech notes, and stack. | |
549 : There should be no need to mess with the stack. | |
550 | |
551 =cut | |
552 | |
553 #--------- | |
554 sub set { | |
555 #--------- | |
556 my( $self, $member, $data ) = @_; | |
557 | |
558 local $_ = "\u$member"; | |
559 SWITCH: { | |
560 /msg/i && do{ $self->{'_msg'} = (defined $data ? $data : 'Unknown error'); last SWITCH; }; | |
561 /type/i && do{ $self->_set_type( $data ); last SWITCH; }; | |
562 /note|tech|stack/i && do{ $self->_set_list_data( $member, $data); last SWITCH}; | |
563 warn "\n*** Invalid or unspecified Err data member: $member\n\n"; | |
564 } | |
565 } | |
566 | |
567 | |
568 =head2 msg | |
569 | |
570 Usage : $message = $err->msg; | |
571 Purpose : Get the main message associated with the exception. | |
572 Returns : String | |
573 Argument : optional string to be used as a delimiter. | |
574 | |
575 See Also : L<get>(), L<string>() | |
576 | |
577 =cut | |
578 | |
579 | |
580 #------- | |
581 sub msg { my($self,$delimiter) = @_; $self->get('msg',$delimiter); } | |
582 #------- | |
583 | |
584 | |
585 =head2 type | |
586 | |
587 Usage : $type = $err->type; | |
588 Purpose : Get the type of Err (warning, exception, fatal) | |
589 Returns : String | |
590 Argument : optional string to be used as a delimiter. | |
591 | |
592 See Also : L<get>(), L<string>() | |
593 | |
594 =cut | |
595 | |
596 #-------- | |
597 sub type { my($self,$delimiter) = @_; $self->get('type',$delimiter); } | |
598 #-------- | |
599 | |
600 | |
601 =head2 note | |
602 | |
603 Usage : $note = $err->note; | |
604 : $note = $err->note('<P>'); | |
605 Purpose : Get any general note associated with the exception. | |
606 Returns : String | |
607 Argument : optional string to be used as a delimiter. | |
608 | |
609 See Also : L<get>(), L<string>() | |
610 | |
611 =cut | |
612 | |
613 #--------- | |
614 sub note { my($self,$delimiter) = @_; $self->get('note',$delimiter); } | |
615 #--------- | |
616 | |
617 | |
618 =head2 tech | |
619 | |
620 Usage : $tech = $err->tech; | |
621 : $tech = $err->tech('<P>'); | |
622 Purpose : Get any technical note associate with the exception. | |
623 Returns : String | |
624 Argument : optional string to be used as a delimiter. | |
625 | |
626 See Also : L<get>(), L<string>() | |
627 | |
628 =cut | |
629 | |
630 #------------ | |
631 sub tech { my($self,$delimiter) = @_; $self->get('tech',$delimiter); } | |
632 #------------ | |
633 | |
634 | |
635 | |
636 =head2 stack | |
637 | |
638 Usage : $stack = $err->stack; | |
639 : $stack = $err->stack('<P>'); | |
640 Purpose : Get the call stack for the exception. | |
641 Returns : String | |
642 Argument : optional string to be used as a delimiter. | |
643 | |
644 See Also : L<get>(), L<string>() | |
645 | |
646 =cut | |
647 | |
648 #---------- | |
649 sub stack { my($self,$delimiter) = @_; $self->get('stack',$delimiter); } | |
650 #---------- | |
651 | |
652 | |
653 | |
654 =head2 context | |
655 | |
656 Usage : $context = $err->context; | |
657 : $context = $err->context('<P>'); | |
658 Purpose : Get the containment context of the object which generated the exception. | |
659 Returns : String | |
660 Argument : optional string to be used as a delimiter. | |
661 | |
662 See Also : L<get>(), L<string>() | |
663 | |
664 =cut | |
665 | |
666 #------------ | |
667 sub context { my($self,$delimiter) = @_; $self->get('context',$delimiter); } | |
668 #------------ | |
669 | |
670 | |
671 | |
672 =head2 get | |
673 | |
674 Usage : $err->get($member, $delimiter); | |
675 Purpose : Get specific data from the Err.pm object. | |
676 Returns : String in scalar context. | |
677 : Array in list context. | |
678 Argument : $member = any of qw(msg type note tech stack context) or combination. | |
679 : $delimiter = optional string to be used as a delimiter | |
680 : between member data. | |
681 | |
682 See Also : L<string>(), L<msg>(), L<note>(), L<tech>(), L<type>(), L<context>(), L<stack>() | |
683 | |
684 =cut | |
685 | |
686 #--------- | |
687 sub get { | |
688 #--------- | |
689 my( $self, $member, $delimiter ) = @_; | |
690 | |
691 my $outer_delim = $delimiter || "\n"; | |
692 # my $outer_delim = ($CGI ? "\n<P>" : $delimiter); ## Subtle bug here. | |
693 | |
694 my (@out); | |
695 local $_ = $member; | |
696 SWITCH: { | |
697 /type/i && do{ push (@out, $self->{'_type'},$outer_delim) }; | |
698 # /msg/i && do{ print "getting msg";<STDIN>; push (@out, (defined $self->{'_msg'} ? $self->{'_msg'} : ''),$outer_delim); print "msg: @out<---";<STDIN>; }; | |
699 /msg/i && do{ push (@out, (defined $self->{'_msg'} ? $self->{'_msg'} : ''),$outer_delim); }; | |
700 /note/i && do{ push (@out, $self->_get_list_data('note', $delimiter ),$outer_delim) }; | |
701 /tech/i && do{ push (@out, $self->_get_list_data('tech', $delimiter ),$outer_delim) }; | |
702 /stack/i && do{ push (@out, $self->_get_list_data('stack', $delimiter ),$outer_delim) }; | |
703 /context/i && do{ push (@out, $self->_get_list_data('context', $delimiter ),$outer_delim) }; | |
704 | |
705 ## CAN'T USE THE FOLLOWING FORM SINCE IT FAILS WHEN $member EQUALS 'msgnote'. | |
706 # /note|tech|stack/ && do{ push @out, $self->_get_list_data( $_, $delimiter ); }; | |
707 | |
708 last SWITCH; | |
709 $self->warn("Invalid or undefined Err data member ($member)."); | |
710 } | |
711 # $DEBUG && do{ print STDERR "OUTER DELIM = $outer_delim \nOUT: \n @out <---";<STDIN>;}; | |
712 wantarray ? @out : join('',@out); | |
713 } | |
714 | |
715 | |
716 | |
717 =head2 _get_list_data | |
718 | |
719 Usage : n/a; internal method used by get() | |
720 Purpose : Gets data for members which are list refs (note, tech, stack, context) | |
721 Returns : Array | |
722 Argument : ($member, $delimiter) | |
723 | |
724 See Also : L<get>() | |
725 | |
726 =cut | |
727 | |
728 #------------------- | |
729 sub _get_list_data { | |
730 #------------------- | |
731 my( $self, $member, $delimiter ) = @_; | |
732 $delimiter ||= "\t"; | |
733 # Sensitive to data member name changes. | |
734 $member = "_\l$member"; | |
735 return if !defined $self->{$member}; | |
736 join( $delimiter, @{$self->{$member}} ); | |
737 } | |
738 | |
739 | |
740 | |
741 =head2 get_all | |
742 | |
743 Usage : (same as get()) | |
744 Purpose : Get specific data from all errors in an Err.pm object. | |
745 Returns : Array in list context. | |
746 : String in scalar context. | |
747 Argument : (same as get()) | |
748 | |
749 See Also : L<get>() | |
750 | |
751 =cut | |
752 | |
753 #------------ | |
754 sub get_all { | |
755 #------------ | |
756 my( $self, $member, $delimiter ) = @_; | |
757 | |
758 if( $self->size() == 1) { | |
759 return $self->get( $member, $delimiter); | |
760 } else { | |
761 my $err = $self; | |
762 | |
763 ### Return data from multiple errors in a list. | |
764 if(wantarray) { | |
765 my @out; | |
766 do{ push @out, $err->get( $member); | |
767 } while($err = $err->prev()); | |
768 return @out; | |
769 | |
770 } else { | |
771 ### Return data from multiple errors in a string with each error's data | |
772 ### bracketed by a "Error #n\n" line and two delimiters. | |
773 my $out = ''; | |
774 if($err->size() == 1) { | |
775 $out = $err->get( $member, $delimiter); | |
776 } else { | |
777 do{ #$out .= "Error #${\$err->rank()}$delimiter"; | |
778 $out .= $err->get( $member, $delimiter); | |
779 $out .= $delimiter.$delimiter; | |
780 } while($err = $err->prev()); | |
781 } | |
782 return $out; | |
783 } | |
784 } | |
785 } | |
786 | |
787 ##################################################################################### | |
788 ## INSTANCE METHODS ## | |
789 ##################################################################################### | |
790 | |
791 | |
792 =head2 _add_note | |
793 | |
794 Usage : n/a; internal method called by _add_list_data() | |
795 Purpose : adds a new note. | |
796 | |
797 See Also : L<_add_list_data>() | |
798 | |
799 =cut | |
800 | |
801 #--------------- | |
802 sub _add_note { | |
803 #--------------- | |
804 my( $self, $data ) = @_; | |
805 | |
806 if( defined $self->{'_note'} ) { | |
807 push @{ $self->{'_note'}}, $data; | |
808 } else { | |
809 $self->_set_list_data('note', $data ); | |
810 } | |
811 } | |
812 | |
813 #---------------------------------------------------------------------- | |
814 =head2 _add_tech() | |
815 | |
816 Usage : n/a; internal method called by _add_list_data() | |
817 Purpose : adds a new technical note. | |
818 | |
819 See Also : L<_add_list_data>() | |
820 | |
821 =cut | |
822 | |
823 #------------- | |
824 sub _add_tech { | |
825 #------------- | |
826 my( $self, $data ) = @_; | |
827 | |
828 if( defined $self->{'_tech'} ) { | |
829 push @{ $self->{'_tech'}}, $data; | |
830 } else { | |
831 $self->_set_list_data('Tech', $data ); | |
832 } | |
833 } | |
834 | |
835 | |
836 =head2 _add_list_data | |
837 | |
838 Usage : n/a; called by _set_list_data() | |
839 Purpose : adds a new note or tech note. | |
840 | |
841 See Also : L<_set_list_data>() | |
842 | |
843 =cut | |
844 | |
845 #-------------------- | |
846 sub _add_list_data { | |
847 #-------------------- | |
848 my( $self, $member, $data ) = @_; | |
849 | |
850 local $_ = $member; | |
851 SWITCH: { | |
852 /note/i && do{ $self->_add_note( $data ); }; | |
853 /tech/i && do{ $self->_add_tech( $data ); }; | |
854 } | |
855 } | |
856 | |
857 | |
858 | |
859 =head2 print | |
860 | |
861 Usage : $err->print; | |
862 Purpose : Prints Err data to STDOUT or a FileHandle. | |
863 Returns : Call to print | |
864 Argument : Named parameters for string() | |
865 Comments : Uses string() to get data. | |
866 | |
867 See Also : L<string>() | |
868 | |
869 =cut | |
870 | |
871 #----------- | |
872 sub print { | |
873 #----------- | |
874 my( $self, %param ) = @_; | |
875 # my $OUT = $self->parent->fh(); | |
876 # print $OUT $self->string(%param); | |
877 print $self->string(%param); | |
878 } | |
879 | |
880 | |
881 =head2 string | |
882 | |
883 Usage : $err->string( %named_parameters); | |
884 Purpose : Stringify the data contained in the Err.pm object. | |
885 Example : print STDERR $err->string; | |
886 Returns : String | |
887 Argument : Named parameters (optional) passed to | |
888 : Bio::Root::IOManager::set_display(). | |
889 | |
890 See Also : L<print>(), L<_build_from_string>(), B<Bio::Root::IOManager::set_display()> | |
891 | |
892 =cut | |
893 | |
894 #----------- | |
895 sub string { | |
896 #----------- | |
897 my( $self, @param ) = @_; | |
898 | |
899 my %param = @param; | |
900 $self->set_display( @param ); | |
901 my $show = $self->show; | |
902 my $out = $param{-BEEP} ? "\a" : ''; | |
903 | |
904 my $err = $param{-CURRENT} ? $self->last : $self->first; | |
905 | |
906 # my $err1 = $err; | |
907 # my $errL = $self->last; | |
908 # print "\n\nERR 1: ${\$err1->msg}"; | |
909 # print "\nERR L: ${\$errL->msg}";<STDIN>; | |
910 | |
911 my $numerate = $err->size() >1; | |
912 my $count = 0; | |
913 my ($title); | |
914 my $hasnote = defined $self->{'_note'}; | |
915 my $hastech = defined $self->{'_tech'}; | |
916 | |
917 while (ref $err) { | |
918 $count++; | |
919 # $out .= sprintf "\nERROR #%d:", $count; | |
920 | |
921 if(not $title = $err->{'_type'}) { | |
922 $err = $err->next(); | |
923 next; | |
924 } | |
925 if( $numerate) { | |
926 ## The rank data is a bit screwy at present. | |
927 $out .= sprintf "\n%s %s %s\n", '-'x 20, $title,'-'x 20; | |
928 } else { | |
929 $out .= sprintf "\n%s %s %s\n", '-'x20, $title,'-'x20; | |
930 } | |
931 $show =~ /msg|default/i and $out .= "MSG: " . $err->msg("\n"); | |
932 $show =~ /note|default/i and $hasnote and $out .= "NOTE: ".$err->note("\n"); | |
933 $show =~ /tech|default/i and $hastech and $out .= "TECH: ".$err->tech("\n"); | |
934 $show =~ /context|default/i and $out .= "CONTEXT: ".$err->context("\n"); | |
935 $show =~ /stack|default/i and $out .= "STACK: \n".$err->stack("\n"); | |
936 $out .= sprintf "%s%s%s\n",'-'x 20, '-'x (length($title)+2), '-'x 20; | |
937 | |
938 # print "$ID: string: cumulative err:\n$out\n";<STDIN>; | |
939 | |
940 $err = $err->next(); | |
941 } | |
942 | |
943 $out; | |
944 } | |
945 | |
946 | |
947 | |
948 =head2 is_fatal | |
949 | |
950 Usage : $err->is_fatal; | |
951 Purpose : Determine if the error is of type 'FATAL' | |
952 Returns : Boolean | |
953 Status : Experimental, Deprecated | |
954 | |
955 =cut | |
956 | |
957 #-------------- | |
958 sub is_fatal { my $self = shift; $self->{'_type'} eq 'FATAL'; } | |
959 #-------------- | |
960 | |
961 ##################################################################################### | |
962 ## CLASS METHODS ## | |
963 ##################################################################################### | |
964 | |
965 | |
966 =head2 throw | |
967 | |
968 Usage : throw($object, [message], [note], [technical note]); | |
969 : This method is exported. | |
970 Purpose : Class method version of Bio::Root::Object::throw(). | |
971 Returns : die()s with the contents of the Err object in a string. | |
972 : If the global strictness is less than -1, die is not called and | |
973 : the error is printed to STDERR. | |
974 Argument : [0] = object throwing the error. | |
975 : [1] = optional message about the error. | |
976 : [2] = optional note about the error. | |
977 : [3] = optional technical note about the error. | |
978 Comments : The glogal verbosity level is not used. For verbosity-sensitive | |
979 : behavior, use Bio::Root::Object::throw(). | |
980 Status : Experimental | |
981 : This method is an alternative to Bio::Root::Object::throw() | |
982 : and is not as well developed or documented as that method. | |
983 | |
984 See Also : L<warning>(), B<Bio::Root::Object::throw()> B<Bio::Root::Global::strictness>() | |
985 | |
986 =cut | |
987 | |
988 #---------- | |
989 sub throw { | |
990 #---------- | |
991 my($obj, @param) = @_; | |
992 | |
993 # print "Throwing exception for object ${\ref $self} \"${\$self->name}\"\n"; | |
994 my $err = new Bio::Root::Err( | |
995 -MSG =>$param[0], | |
996 -NOTE =>$param[1], | |
997 -TECH =>$param[2], | |
998 -STACK =>scalar(Bio::Root::Object::stack_trace($obj,2)), | |
999 -CONTEXT =>Bio::Root::Object::containment($obj), | |
1000 -TYPE =>'EXCEPTION', | |
1001 # -PARENT =>$obj, | |
1002 ); | |
1003 | |
1004 if(strictness() < -1) { | |
1005 print STDERR $err->string(-BEEP=>1) unless verbosity() < 0; | |
1006 } else { | |
1007 die $err->string; | |
1008 } | |
1009 | |
1010 0; | |
1011 } | |
1012 | |
1013 | |
1014 =head2 warning | |
1015 | |
1016 Usage : warning($object, [message], [note], [technical note]); | |
1017 : This method is exported. | |
1018 Purpose : Class method version of Bio::Root::Object::warn(). | |
1019 Returns : Prints the contents of the error to STDERR and returns false (0). | |
1020 : If the global strictness() is > 1, warn() calls are converted | |
1021 : into throw() calls. | |
1022 Argument : [0] = object producing the warning. | |
1023 : [1] = optional message about the error. | |
1024 : [2] = optional note about the error. | |
1025 : [3] = optional technical note about the error. | |
1026 : | |
1027 Comments : The glogal verbosity level is not used. For verbosity-sensitive | |
1028 : behavior, use Bio::Root::Object::warn(). | |
1029 Status : Experimental | |
1030 : This method is an alternative to Bio::Root::Object::warn() | |
1031 : and is not as well developed or documented as that method. | |
1032 | |
1033 See Also : L<throw>, B<Bio::Root::Object::warn()>, B<Bio::Root::Global::strictness()> | |
1034 | |
1035 =cut | |
1036 | |
1037 #----------- | |
1038 sub warning { | |
1039 #----------- | |
1040 my($obj, @param) = @_; | |
1041 | |
1042 # print "Throwing exception for object ${\ref $self} \"${\$self->name}\"\n"; | |
1043 my $err = new Bio::Root::Err( | |
1044 -MSG =>$param[0], | |
1045 -NOTE =>$param[1], | |
1046 -TECH =>$param[2], | |
1047 -STACK =>scalar(Bio::Root::Object::stack_trace($obj,2)), | |
1048 -CONTEXT =>Bio::Root::Object::containment($obj), | |
1049 -TYPE =>'WARNING', | |
1050 # -PARENT =>$obj, | |
1051 ); | |
1052 | |
1053 if(strictness() > 1) { | |
1054 die $err->string; | |
1055 | |
1056 } else { | |
1057 print STDERR $err->string(-BEEP=>1) unless $DONT_WARN; | |
1058 } | |
1059 | |
1060 0; | |
1061 } | |
1062 | |
1063 | |
1064 =head2 format_stack_entry | |
1065 | |
1066 Usage : &format_stack_entry(<class>,<file>,<line>,<class_method>,<has_args>,<wantarray>) | |
1067 : This function is exported. | |
1068 Purpose : Creates a single stack entry given a caller() list. | |
1069 Argument : List of scalars (output of the caller() method). | |
1070 Returns : String = class_method($line) | |
1071 : e.g., Bio::Root::Object::name(1234) | |
1072 | |
1073 =cut | |
1074 | |
1075 #------------------------ | |
1076 sub format_stack_entry { | |
1077 #------------------------ | |
1078 my( $class, $file, $line, $classmethod, $hasargs, $wantarray) = @_; | |
1079 | |
1080 # if($DEBUG) { | |
1081 # print STDERR "format_stack_entry data:\n"; | |
1082 # foreach(@_) {print STDERR "$_\n"; } <STDIN>; | |
1083 # } | |
1084 | |
1085 $classmethod ||= 'unknown class/method'; | |
1086 $line ||= 'unknown line'; | |
1087 return "$classmethod($line)"; | |
1088 } | |
1089 | |
1090 1; | |
1091 __END__ | |
1092 | |
1093 ##################################################################################### | |
1094 # END OF CLASS # | |
1095 ##################################################################################### | |
1096 | |
1097 =head1 FOR DEVELOPERS ONLY | |
1098 | |
1099 =head2 Data Members | |
1100 | |
1101 Information about the various data members of this module is provided for those | |
1102 wishing to modify or understand the code. Two things to bear in mind: | |
1103 | |
1104 =over 4 | |
1105 | |
1106 =item 1 Do NOT rely on these in any code outside of this module. | |
1107 | |
1108 All data members are prefixed with an underscore to signify that they are private. | |
1109 Always use accessor methods. If the accessor doesn't exist or is inadequate, | |
1110 create or modify an accessor (and let me know, too!). | |
1111 | |
1112 =item 2 This documentation may be incomplete and out of date. | |
1113 | |
1114 It is easy for this documentation to become obsolete as this module is still evolving. | |
1115 Always double check this info and search for members not described here. | |
1116 | |
1117 =back | |
1118 | |
1119 An instance of Bio::Root::Err.pm is a blessed reference to a hash containing | |
1120 all or some of the following fields: | |
1121 | |
1122 FIELD VALUE | |
1123 ------------------------------------------------------------------------ | |
1124 _type fatal | warning | exception (one of @Bio::Root::Err::ERR_TYPES). | |
1125 | |
1126 _msg Terse description: Main cause of error. | |
1127 | |
1128 _note List reference. Verbose description: probable cause & troubleshooting for user. | |
1129 | |
1130 _tech List reference. Technical notes of interest to programmer. | |
1131 | |
1132 _stack List reference. Stack trace: list of "class::method(line number)" strings. | |
1133 | |
1134 | |
1135 | |
1136 =cut | |
1137 | |
1138 1; |