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;