File Coverage

blib/lib/OpenPlugin/Exception.pm
Criterion Covered Total %
statement 57 71 80.2
branch 7 16 43.7
condition 5 11 45.4
subroutine 15 19 78.9
pod 2 12 16.6
total 86 129 66.6


line stmt bran cond sub pod time code
1             package OpenPlugin::Exception;
2              
3             # $Id: Exception.pm,v 1.33 2003/05/13 14:59:22 andreychek Exp $
4              
5 5     5   6197 use strict;
  5         12  
  5         295  
6 5     5   988 use base qw( OpenPlugin::Plugin );
  5         9  
  5         1258  
7             #use overload q("") => \&stringify;
8 5     5   37 use overload '""' => sub { $_[0]->to_string };
  5     14   9  
  5         1013  
  14         142  
9 5     5   9043 use Devel::StackTrace();
  5         32056  
  5         2000  
10              
11             $OpenPlugin::Exception::VERSION = sprintf("%d.%02d", q$Revision: 1.33 $ =~ /(\d+)\.(\d+)/);
12              
13             my @STACK = ();
14             my @FIELDS = qw( message package filename line method trace );
15              
16 0     0 0 0 sub type { return 'exception' }
17 46     46 0 2602 sub OP { return $_[0]->{_m}{OP} }
18              
19              
20             ########################################
21             # CLASS METHODS
22              
23             sub log_throw {
24 0     0 0 0 my ( $self, @message ) = @_;
25              
26 0 0       0 my $params = ( ref $message[-1] eq 'HASH' )
27             ? pop( @message ) : {};
28              
29 0         0 my $message = join( '', @message );
30              
31             # We don't want the message to look like it's coming from this method, we
32             # want it to appear as if it was generated by the method which called us
33 0         0 $Log::Log4perl::caller_depth++;
34 0         0 $self->OP->log->fatal( @message );
35 0         0 $Log::Log4perl::caller_depth--;
36              
37 0         0 $self->throw( $message );
38              
39             }
40              
41             sub throw {
42 1     1 0 14 my ( $self, @message ) = @_;
43              
44 1   33     5 my $class = ref( $self ) || $self;
45              
46             # Allow exception's to be rethrown, without further processing
47 1 50       6 if ( ref $message[0] ) {
48 0         0 my $rethrown = $message[0];
49 0 0       0 if ( UNIVERSAL::isa( $rethrown, __PACKAGE__ ) ) {
50 0         0 die $rethrown;
51             }
52             }
53              
54 1 50       6 my $params = ( ref $message[-1] eq 'HASH' )
55             ? pop( @message ) : {};
56              
57 1         4 my $msg = join( '', @message );
58              
59             # Set a default in case throw is called without a value
60 1   50     5 $msg ||= "Nuts, an error has occurred.";
61              
62 1         6 foreach my $field ( $self->get_fields() ) {
63 6 50       13 $self->state( $field, $params->{ $field } ) if ( $params->{ $field } );
64              
65             # Build the accessor methods to our exception properties
66 5     5   51 no strict 'refs';
  5         18  
  5         4133  
67 6 50       8 unless ( defined &{ $field } ) {
  6         118  
68 6     5   15 *{ $field } = sub { return $_[0]->state( $field ); };
  6         26  
  5         15539  
69             }
70             }
71              
72             # Now do the message and the initial trace stuff
73              
74 1         6 $self->state( 'message', $msg );
75              
76 1         4 my @initial_call = $self->custom_caller;
77 1         6 $self->state( 'package', $initial_call[0] );
78 1         3 $self->state( 'filename', $initial_call[1] );
79 1         5 $self->state( 'line', $initial_call[2] );
80 1         5 $self->state( 'method', $initial_call[3] );
81              
82 1         11 $self->state( 'trace', Devel::StackTrace->new());
83              
84 1         6 $self->initialize( $params );
85              
86 1         2 push @STACK, $self;
87              
88 1         10 die $self;
89              
90             }
91              
92             sub custom_caller {
93             # the below could all be just:
94             # my ($pack, $file, $line) = caller(2);
95             # but if we ever bury this further, it'll break. So we do this
96             # little trick stolen and paraphrased first from Carp/Heavy.pm, then
97             # from Log4perl/Logger.pm
98              
99 1     1 0 3 my $i = 0;
100 1         7 my (undef, $localfile, undef) = caller($i++);
101 1         3 my ($pack, $file, $line, $method);
102 1   33     2 do {
103 1         48 ($pack, $file, $line) = caller($i++);
104             } while ($file && $file eq $localfile);
105              
106             # Grab the method name separately, since the subroutine call
107             # doesn't seem to be matched up properly with the other caller()
108             # stuff when we do caller(0). Weird.
109 1         4 $method = (caller($i))[3];
110              
111 1         5 return ( $pack, $file, $line, $method );
112             }
113              
114 1     1 1 2 sub initialize {}
115              
116 2     2 1 1387 sub get_fields { return @FIELDS }
117              
118 1     1 0 554 sub get_stack { return @STACK }
119 1     1 0 536 sub clear_stack { @STACK = () }
120              
121             #sub trace { return $_[0]->state->{ trace } };
122              
123             ########################################
124             # OBJECT METHODS
125              
126             sub creation_location {
127 0     0 0 0 my ( $self ) = @_;
128             return 'Created in package [' . $self->state->{ package } . '] ' .
129             'in method [' . $self->state->{ method } . '] ' .
130             'at file [' . $self->state->{ filename } . '] ' .
131 0         0 'at line [' . $self->state->{ line } . ']';
132             }
133              
134 0     0 0 0 sub stringify { return $_[0]->to_string() }
135             sub to_string {
136 14     14 0 22 my ( $self ) = @_;
137 14         30 my $class = ref $self;
138              
139 14 50       39 return "Invalid -- not called from object." unless ( $class );
140              
141             # Give everything back if it doesn't look like we were meant to be called
142 14 100 66     83 unless (( $self->state ) && ( $self->state->{ message } )) {
143 12         60 return @_;
144             }
145              
146             #no strict 'refs';
147 2         8 return $self->state->{ message }; #unless ( ${ $class . '::ShowTrace' } );
148              
149             #return join( "\n", $_[0]->state->{message}, $_[0]->trace );
150             }
151              
152              
153             1;
154              
155             __END__