File Coverage

blib/lib/Elasticsearch/Error.pm
Criterion Covered Total %
statement 45 59 76.2
branch 17 26 65.3
condition 9 16 56.2
subroutine 7 9 77.7
pod 0 3 0.0
total 78 113 69.0


line stmt bran cond sub pod time code
1             package Elasticsearch::Error;
2             $Elasticsearch::Error::VERSION = '1.05';
3 50     50   287 use Moo;
  50         101  
  50         301  
4              
5             our $DEBUG = 0;
6              
7             @Elasticsearch::Error::Internal::ISA = __PACKAGE__;
8             @Elasticsearch::Error::Param::ISA = __PACKAGE__;
9             @Elasticsearch::Error::NoNodes::ISA = __PACKAGE__;
10             @Elasticsearch::Error::ClusterBlocked::ISA = __PACKAGE__;
11             @Elasticsearch::Error::Request::ISA = __PACKAGE__;
12             @Elasticsearch::Error::Timeout::ISA = __PACKAGE__;
13             @Elasticsearch::Error::Cxn::ISA = __PACKAGE__;
14             @Elasticsearch::Error::Serializer::ISA = __PACKAGE__;
15              
16             @Elasticsearch::Error::Conflict::ISA
17             = ( 'Elasticsearch::Error::Request', __PACKAGE__ );
18              
19             @Elasticsearch::Error::Missing::ISA
20             = ( 'Elasticsearch::Error::Request', __PACKAGE__ );
21              
22             @Elasticsearch::Error::ContentLength::ISA
23             = ( __PACKAGE__, 'Elasticsearch::Error::Request' );
24              
25             @Elasticsearch::Error::Unavailable::ISA
26             = ( 'Elasticsearch::Error::Cxn', __PACKAGE__ );
27              
28             use overload (
29 50         478 '""' => '_stringify',
30             'cmp' => '_compare',
31 50     50   116127 );
  50         61103  
32              
33 50     50   161899 use Data::Dumper();
  50         565459  
  50         47245  
34              
35             #===================================
36             sub new {
37             #===================================
38 112     112 0 2344 my ( $class, $type, $msg, $vars, $caller ) = @_;
39 112 100       388 return $type if ref $type;
40 84   100     256 $caller ||= 0;
41              
42 84         224 my $error_class = 'Elasticsearch::Error::' . $type;
43 84 50       269 $msg = 'Unknown error' unless defined $msg;
44              
45 84 50       258 local $DEBUG = 2 if $type eq 'Internal';
46              
47 84         393 my $stack = $class->_stack;
48              
49 84         742 my $self = bless {
50             type => $type,
51             text => $msg,
52             vars => $vars,
53             stack => $stack,
54             }, $error_class;
55              
56 84         951 return $self;
57             }
58              
59             #===================================
60             sub is {
61             #===================================
62 141     141 0 225 my $self = shift;
63 141         1509 for (@_) {
64 164 100       1572 return 1 if $self->isa("Elasticsearch::Error::$_");
65             }
66 44         267 return 0;
67             }
68              
69             #===================================
70             sub _stringify {
71             #===================================
72 165     165   6284 my $self = shift;
73 165         293 local $Data::Dumper::Terse = 1;
74 165         365 local $Data::Dumper::Indent = !!$DEBUG;
75              
76 165 100       569 unless ( $self->{msg} ) {
77 69         388 my $stack = $self->{stack};
78 69         156 my $caller = $stack->[0];
79 69         600 $self->{msg}
80             = sprintf( "[%s] ** %s, called from sub %s at %s line %d.",
81 69         239 $self->{type}, $self->{text}, @{$caller}[ 3, 1, 2 ] );
82              
83 69 100       400 if ( $self->{vars} ) {
84 54         346 $self->{msg} .= sprintf( " With vars: %s\n",
85             Data::Dumper::Dumper $self->{vars} );
86             }
87              
88 69 50       6880 if ( @$stack > 1 ) {
89 0         0 $self->{msg}
90             .= sprintf( "Stacktrace:\n%s\n", $self->stacktrace($stack) );
91             }
92             }
93 165         946 return $self->{msg};
94              
95             }
96              
97             #===================================
98             sub _compare {
99             #===================================
100 0     0   0 my ( $self, $other, $swap ) = @_;
101 0         0 $self .= '';
102 0 0       0 ( $self, $other ) = ( $other, $self ) if $swap;
103 0         0 return $self cmp $other;
104             }
105              
106             #===================================
107             sub _stack {
108             #===================================
109 84     84   179 my $self = shift;
110 84   50     508 my $caller = shift() || 2;
111              
112 84         154 my @stack;
113 84         351 while ( my @caller = caller( ++$caller ) ) {
114 164 100 100     8373 if ( $caller[0] eq 'Try::Tiny' or $caller[0] eq 'main' ) {
115 25 50       85 next if $caller[3] eq '(eval)';
116 25 50       133 if ( $caller[3] =~ /^(.+)::__ANON__\[(.+):(\d+)\]$/ ) {
117 0         0 @caller = ( $1, $2, $3, '(ANON)' );
118             }
119             }
120             next
121 164 50 33     1337 if $caller[0] =~ /^Elasticsearch/
      66        
122             and $DEBUG < 2 || $caller[3] eq 'Try::Tiny::try';
123 82         388 push @stack, [ @caller[ 0, 1, 2, 3 ] ];
124 82 50       456 last unless $DEBUG > 1;
125             }
126 84         313 return \@stack;
127             }
128              
129             #===================================
130             sub stacktrace {
131             #===================================
132 0     0 0   my $self = shift;
133 0   0       my $stack = shift || $self->_stack();
134              
135 0           my $o = sprintf "%s\n%-4s %-40s %-5s %s\n%s\n",
136             '-' x 60, '#', 'Package', 'Line', 'Sub-routine', '-' x 60;
137              
138 0           my $i = 1;
139 0           for (@$stack) {
140 0           $o .= sprintf "%-4d %-40s %4d %s\n", $i++, @{$_}[ 0, 2, 3 ];
  0            
141             }
142              
143 0           return $o .= ( '-' x 60 ) . "\n";
144             }
145             1;
146              
147             # ABSTRACT: Errors thrown by Elasticsearch
148              
149             __END__
150              
151             =pod
152              
153             =encoding UTF-8
154              
155             =head1 NAME
156              
157             Elasticsearch::Error - Errors thrown by Elasticsearch
158              
159             =head1 VERSION
160              
161             version 1.05
162              
163             =head1 DESCRIPTION
164              
165             Errors thrown by Elasticsearch are error objects, which can include
166             a stack trace and information to help debug problems. An error object
167             consists of the following:
168              
169             {
170             type => $type, # eg Missing
171             text => 'Error message',
172             vars => {...}, # vars which may help to explain the error
173             stack => [...], # a stack trace
174             }
175              
176             The C<$Elasticsearch::Error::DEBUG> variable can be set to C<1> or C<2>
177             to increase the verbosity of errors.
178              
179             =head1 ERROR CLASSES
180              
181             The following error classes are defined:
182              
183             =over
184              
185             =item * C<Elasticsearch::Error::Param>
186              
187             A bad parameter has been passed to a method.
188              
189             =item * C<Elasticsearch::Error::Request>
190              
191             There was some generic error performing your request in Elasticsearch.
192             This error is triggered by HTTP status codes C<400> and C<500>. This class
193             has the following sub-classes:
194              
195             =over
196              
197             =item * C<Elasticsearch::Error::Missing>
198              
199             A resource that you requested was not found. These errors are triggered
200             by the C<404> HTTP status code.
201              
202             =item * C<Elastisearch::Error::Conflict>
203              
204             Your request could not be performed because of some conflict. For instance,
205             if you try to delete a document with a particular version number, and the
206             document has already changed, it will throw a C<Conflict> error. If it can,
207             it will include the C<current_version> in the error vars. This error
208             is triggered by the C<409> HTTP status code.
209              
210             =item * C<Elasticsearch::Error::ContentLength>
211              
212             The request body was longer than the
213             L<max_content_length|Elasticsearch::Role::Cxn::HTTP/max_content_length>.
214              
215             =back
216              
217             =item * C<Elasticsearch::Error::Timeout>
218              
219             The request timed out.
220              
221             =item * C<Elasticsearch::Error::Cxn>
222              
223             There was an error connecting to a node in the cluster. This error
224             indicates node failure and will be retried on another node.
225             This error has the following sub-class:
226              
227             =over
228              
229             =item * C<Elasticsearch::Error::Unavailable>
230              
231             The current node is unable to handle your request at the moment. Your
232             request will be retried on another node. This error is triggered by
233             the C<503> HTTP status code.
234              
235             =back
236              
237             =item * C<Elasticsearch::Error::ClusterBlocked>
238              
239             The cluster was unable to process the request because it is currently blocking,
240             eg there are not enough master nodes to form a cluster. This error is
241             triggered by the C<403> HTTP status code.
242              
243             =item * C<Elasticsearch::Error::Serializer>
244              
245             There was an error serializing a variable or deserializing a string.
246              
247             =item * C<Elasticsarch::Error::Internal>
248              
249             An internal error occurred - please report this as a bug in
250             this module.
251              
252             =back
253              
254             =head1 AUTHOR
255              
256             Clinton Gormley <drtech@cpan.org>
257              
258             =head1 COPYRIGHT AND LICENSE
259              
260             This software is Copyright (c) 2014 by Elasticsearch BV.
261              
262             This is free software, licensed under:
263              
264             The Apache License, Version 2.0, January 2004
265              
266             =cut