File Coverage

blib/lib/SPOPS/Exception.pm
Criterion Covered Total %
statement 53 61 86.8
branch 5 12 41.6
condition n/a
subroutine 14 17 82.3
pod 0 10 0.0
total 72 100 72.0


line stmt bran cond sub pod time code
1             package SPOPS::Exception;
2              
3             # $Id: Exception.pm,v 3.5 2004/06/02 00:48:21 lachoy Exp $
4              
5 23     23   1004 use strict;
  23         47  
  23         1220  
6 23     23   132 use base qw( Class::Accessor Exporter );
  23         50  
  23         26875  
7 23     23   64364 use overload '""' => \&stringify;
  23         59  
  23         451  
8 23     23   53072 use Devel::StackTrace;
  23         103392  
  23         748  
9 23     23   17548 use SPOPS::Error;
  23         91  
  23         1993  
10              
11             $SPOPS::Exception::VERSION = sprintf("%d.%02d", q$Revision: 3.5 $ =~ /(\d+)\.(\d+)/);
12             @SPOPS::Exception::EXPORT_OK = qw( spops_error );
13              
14 23     23   141 use constant DEBUG => 0;
  23         84  
  23         15860  
15              
16             my @STACK = ();
17             my @FIELDS = qw( message package filename line method trace );
18             SPOPS::Exception->mk_accessors( @FIELDS );
19              
20             ########################################
21             # SHORTCUT
22              
23 0     0 0 0 sub spops_error { goto &throw( 'SPOPS::Exception', @_ ) }
24              
25              
26             ########################################
27             # CLASS METHODS
28              
29             sub throw {
30 5     5 0 6390 my ( $class, @message ) = @_;
31              
32 5 50       25 if ( ref $message[0] ) {
33 0         0 my $rethrown = $message[0];
34 0 0       0 if ( UNIVERSAL::isa( $rethrown, __PACKAGE__ ) ) {
35 0         0 die $rethrown;
36             }
37             }
38              
39 5 50       25 my $params = ( ref $message[-1] eq 'HASH' )
40             ? pop( @message ) : {};
41 5         19 my $msg = join( '', @message );
42              
43 5         16 my $self = bless( {}, $class );
44              
45             # Do all the fields
46              
47 5         19 foreach my $field ( $self->get_fields ) {
48 40 50       86 $self->$field( $params->{ $field } ) if ( $params->{ $field } );
49             }
50              
51             # Now do the message and the initial trace stuff
52              
53 5         67 $self->message( $msg );
54              
55 5         589 my @initial_call = caller;
56 5         32 $self->package( $initial_call[0] );
57 5         77 $self->filename( $initial_call[1] );
58 5         69 $self->line( $initial_call[2] );
59              
60             # Grab the method name separately, since the subroutine call
61             # doesn't seem to be matched up properly with the other caller()
62             # stuff when we do caller(0). Weird.
63              
64 5         64 my @added_call = caller(1);
65 5         18 $added_call[3] =~ s/^.*:://;
66 5         30 $self->method( $added_call[3] );
67              
68 5         89 $self->trace( Devel::StackTrace->new );
69              
70 5         1234 DEBUG && warn "[$class] thrown: ", $self->message, "\n";
71              
72 5         27 $self->initialize( $params );
73              
74 5         12 push @STACK, $self;
75              
76             # BACKWARDS COMPATIBILITY (will remove before 1.0)
77              
78 5         27 $self->fill_error_variables;
79              
80 5         68 die $self;
81             }
82              
83 5     5 0 8 sub initialize {}
84              
85 5     5 0 26 sub get_fields { return @FIELDS }
86              
87 4     4 0 1864 sub get_stack { return @STACK }
88 0     0 0 0 sub clear_stack { @STACK = () }
89              
90              
91             ########################################
92             # OBJECT METHODS
93              
94             sub creation_location {
95 0     0 0 0 my ( $self ) = @_;
96 0         0 return 'Created in package [' . $self->package . '] ' .
97             'in method [' . $self->method . ']; ' .
98             'at file [' . $self->filename . '] ' .
99             'at line [' . $self->line . ']';
100             }
101              
102 4     4 0 23258 sub stringify { return $_[0]->to_string() }
103              
104             sub to_string {
105 2     2 0 5 my ( $self ) = @_;
106 2         4 my $class = ref $self;
107 2 50       8 return "Invalid -- not called from object." unless ( $class );
108              
109 23     23   151 no strict 'refs';
  23         70  
  23         4040  
110 2 50       3 return $self->message() unless ( ${ $class . '::ShowTrace' } );
  2         20  
111 0         0 return join( "\n", $self->message, $self->trace->as_string );
112             }
113              
114             # BACKWARDS COMPATIBILITY (will remove before 1.0)
115              
116             sub fill_error_variables {
117 5     5 0 11 my ( $self ) = @_;
118 5         15 SPOPS::Error->set({ user_msg => $self->message, system_msg => $self->message,
119             package => $self->package, method => $self->method,
120             filename => $self->filename, line => $self->line });
121             }
122              
123             1;
124              
125             __END__