File Coverage

blib/lib/XML/LibXML/Error.pm
Criterion Covered Total %
statement 181 194 93.3
branch 33 42 78.5
condition 11 17 64.7
subroutine 49 54 90.7
pod 3 6 50.0
total 277 313 88.5


line stmt bran cond sub pod time code
1             # $Id: Error.pm,v 1.1.2.1 2004/04/20 20:09:48 pajas Exp $
2             #
3             # This is free software, you may use it and distribute it under the same terms as
4             # Perl itself.
5             #
6             # Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
7             #
8             #
9             package XML::LibXML::Error;
10              
11 66     66   468 use strict;
  66         138  
  66         1988  
12 66     66   320 use warnings;
  66         127  
  66         1816  
13              
14             # To avoid a "Deep recursion on subroutine as_string" warning
15 66     66   337 no warnings 'recursion';
  66         125  
  66         2311  
16              
17 66     66   41775 use Encode ();
  66         733105  
  66         2031  
18              
19 66     66   500 use vars qw(@error_domains $VERSION $WARNINGS);
  66         143  
  66         8675  
20             use overload
21             '""' => \&as_string,
22             'eq' => sub {
23 0     0   0 ("$_[0]" eq "$_[1]")
24             },
25             'cmp' => sub {
26 14     14   4537 ("$_[0]" cmp "$_[1]")
27             },
28 66     66   80761 fallback => 1;
  66         65669  
  66         851  
29              
30             $WARNINGS = 0; # 0: suppress, 1: report via warn, 2: report via die
31             $VERSION = "2.0207"; # VERSION TEMPLATE: DO NOT CHANGE
32              
33 66     66   7865 use constant XML_ERR_NONE => 0;
  66         149  
  66         4369  
34 66     66   412 use constant XML_ERR_WARNING => 1; # A simple warning
  66         170  
  66         3571  
35 66     66   445 use constant XML_ERR_ERROR => 2; # A recoverable error
  66         134  
  66         3763  
36 66     66   430 use constant XML_ERR_FATAL => 3; # A fatal error
  66         188  
  66         3850  
37              
38 66     66   512 use constant XML_ERR_FROM_NONE => 0;
  66         153  
  66         3881  
39 66     66   520 use constant XML_ERR_FROM_PARSER => 1; # The XML parser
  66         153  
  66         3849  
40 66     66   496 use constant XML_ERR_FROM_TREE => 2; # The tree module
  66         189  
  66         4131  
41 66     66   503 use constant XML_ERR_FROM_NAMESPACE => 3; # The XML Namespace module
  66         188  
  66         3502  
42 66     66   417 use constant XML_ERR_FROM_DTD => 4; # The XML DTD validation
  66         167  
  66         3298  
43 66     66   417 use constant XML_ERR_FROM_HTML => 5; # The HTML parser
  66         1417  
  66         3671  
44 66     66   435 use constant XML_ERR_FROM_MEMORY => 6; # The memory allocator
  66         135  
  66         3290  
45 66     66   418 use constant XML_ERR_FROM_OUTPUT => 7; # The serialization code
  66         125  
  66         3723  
46 66     66   531 use constant XML_ERR_FROM_IO => 8; # The Input/Output stack
  66         147  
  66         3693  
47 66     66   410 use constant XML_ERR_FROM_FTP => 9; # The FTP module
  66         165  
  66         3441  
48 66     66   427 use constant XML_ERR_FROM_HTTP => 10; # The FTP module
  66         139  
  66         3402  
49 66     66   470 use constant XML_ERR_FROM_XINCLUDE => 11; # The XInclude processing
  66         154  
  66         3337  
50 66     66   409 use constant XML_ERR_FROM_XPATH => 12; # The XPath module
  66         147  
  66         3316  
51 66     66   405 use constant XML_ERR_FROM_XPOINTER => 13; # The XPointer module
  66         156  
  66         3364  
52 66     66   415 use constant XML_ERR_FROM_REGEXP => 14; # The regular expressions module
  66         143  
  66         3256  
53 66     66   418 use constant XML_ERR_FROM_DATATYPE => 15; # The W3C XML Schemas Datatype module
  66         146  
  66         3510  
54 66     66   444 use constant XML_ERR_FROM_SCHEMASP => 16; # The W3C XML Schemas parser module
  66         175  
  66         3747  
55 66     66   409 use constant XML_ERR_FROM_SCHEMASV => 17; # The W3C XML Schemas validation module
  66         194  
  66         3458  
56 66     66   436 use constant XML_ERR_FROM_RELAXNGP => 18; # The Relax-NG parser module
  66         173  
  66         3435  
57 66     66   427 use constant XML_ERR_FROM_RELAXNGV => 19; # The Relax-NG validator module
  66         187  
  66         3319  
58 66     66   399 use constant XML_ERR_FROM_CATALOG => 20; # The Catalog module
  66         150  
  66         3291  
59 66     66   483 use constant XML_ERR_FROM_C14N => 21; # The Canonicalization module
  66         143  
  66         3525  
60 66     66   443 use constant XML_ERR_FROM_XSLT => 22; # The XSLT engine from libxslt
  66         156  
  66         3389  
61 66     66   420 use constant XML_ERR_FROM_VALID => 23; # The DTD validation module with valid context
  66         185  
  66         3286  
62 66     66   443 use constant XML_ERR_FROM_CHECK => 24; # The error-checking module
  66         151  
  66         3450  
63 66     66   418 use constant XML_ERR_FROM_WRITER => 25; # The xmlwriter module
  66         145  
  66         3373  
64 66     66   395 use constant XML_ERR_FROM_MODULE => 26; # The dynamically-loaded module module
  66         136  
  66         3505  
65 66     66   398 use constant XML_ERR_FROM_I18N => 27; # The module handling character conversion
  66         161  
  66         3301  
66 66     66   415 use constant XML_ERR_FROM_SCHEMATRONV=> 28; # The Schematron validator module
  66         148  
  66         11323  
67              
68             @error_domains = ("", "parser", "tree", "namespace", "validity",
69             "HTML parser", "memory", "output", "I/O", "ftp",
70             "http", "XInclude", "XPath", "xpointer", "regexp",
71             "Schemas datatype", "Schemas parser", "Schemas validity",
72             "Relax-NG parser", "Relax-NG validity",
73             "Catalog", "C14N", "XSLT", "validity", "error-checking",
74             "xmlwriter", "dynamic loading", "i18n",
75             "Schematron validity");
76              
77             my $MAX_ERROR_PREV_DEPTH = 100;
78              
79             for my $field (qw
80             str1 str2 str3 num1 num2 __prev_depth>) {
81 2824     2824   7333 my $method = sub { $_[0]{$field} };
82 66     66   521 no strict 'refs';
  66         150  
  66         65085  
83             *$field = $method;
84             }
85              
86             {
87              
88             sub new {
89 2582     2582 0 4048 my ($class,$xE) = @_;
90 2582         3304 my $terr;
91 2582 100       4878 if (ref($xE)) {
92 2578         14226 my ($context,$column) = $xE->context_and_column();
93 2578 100       26793 $terr =bless {
94             domain => $xE->domain(),
95             level => $xE->level(),
96             code => $xE->code(),
97             message => $xE->message(),
98             file => $xE->file(),
99             line => $xE->line(),
100             str1 => $xE->str1(),
101             str2 => $xE->str2(),
102             str3 => $xE->str3(),
103             num1 => $xE->num1(),
104             num2 => $xE->num2(),
105             __prev_depth => 0,
106             (defined($context) ?
107             (
108             context => $context,
109             column => $column,
110             ) : ()),
111             }, $class;
112             } else {
113             # !!!! problem : got a flat error
114             # warn("PROBLEM: GOT A FLAT ERROR $xE\n");
115 4         31 $terr =bless {
116             domain => 0,
117             level => 2,
118             code => -1,
119             message => $xE,
120             file => undef,
121             line => undef,
122             str1 => undef,
123             str2 => undef,
124             str3 => undef,
125             num1 => undef,
126             num2 => undef,
127             __prev_depth => 0,
128             }, $class;
129             }
130 2582         5119 return $terr;
131             }
132              
133             sub _callback_error {
134             #print "CALLBACK\n";
135 2581     2581   8322 my ($xE,$prev) = @_;
136 2581         3414 my $terr;
137 2581         4608 $terr=XML::LibXML::Error->new($xE);
138 2581 100 66     6792 if ($terr->{level} == XML_ERR_WARNING and $WARNINGS!=2) {
139 6 50       25 warn $terr if $WARNINGS;
140 6         117 return $prev;
141             }
142             #unless ( defined $terr->{file} and length $terr->{file} ) {
143             # this would make it easier to recognize parsed strings
144             # but it breaks old implementations
145             # [CG] $terr->{file} = 'string()';
146             #}
147             #warn "Saving the error ",$terr->dump;
148              
149 2575 100       4340 if (ref($prev))
150             {
151 2415 100       4008 if ($prev->__prev_depth() >= $MAX_ERROR_PREV_DEPTH)
152             {
153 2111         27656 return $prev;
154             }
155 304         508 $terr->{_prev} = $prev;
156 304         629 $terr->{__prev_depth} = $prev->__prev_depth() + 1;
157             }
158             else
159             {
160 160 50 33     577 $terr->{_prev} = defined($prev) && length($prev) ? XML::LibXML::Error->new($prev) : undef;
161             }
162 464         10480 return $terr;
163             }
164             sub _instant_error_callback {
165 0     0   0 my $xE = shift;
166 0         0 my $terr= XML::LibXML::Error->new($xE);
167 0         0 print "Reporting an instanteous error ",$terr->dump;
168 0         0 die $terr;
169             }
170             sub _report_warning {
171 3     3   19 my ($saved_error) = @_;
172             #print "CALLBACK WARN\n";
173 3 50       15 if ( defined $saved_error ) {
174             #print "reporting a warning ",$saved_error->dump;
175 3         35 warn $saved_error;
176             }
177             }
178             sub _report_error {
179 153     153   490 my ($saved_error) = @_;
180             #print "CALLBACK ERROR: $saved_error\n";
181 153 50       506 if ( defined $saved_error ) {
182 153         826 die $saved_error;
183             }
184             }
185             }
186              
187              
188             # backward compatibility
189 0     0 0 0 sub int1 { $_[0]->num1 }
190 0     0 0 0 sub int2 { $_[0]->num2 }
191              
192             sub domain {
193 977     977 1 2882 my ($self)=@_;
194 977 50       1993 return undef unless ref($self);
195 977         1427 my $domain = $self->{domain};
196             # Newer versions of libxml2 might yield errors in domains that aren't
197             # listed above. Invent something reasonable in that case.
198 977 100       2979 return $domain < @error_domains ? $error_domains[$domain] : "domain_$domain";
199             }
200              
201             sub as_string {
202 974     974 1 18571 my ($self)=@_;
203 974         1350 my $msg = "";
204 974         1407 my $level;
205              
206 974 100       2055 if (defined($self->{_prev})) {
207 588         1266 $msg = $self->{_prev}->as_string;
208             }
209              
210 974 50 66     4330 if ($self->{level} == XML_ERR_NONE) {
    50          
    50          
211 0         0 $level = "";
212             } elsif ($self->{level} == XML_ERR_WARNING) {
213 0         0 $level = "warning";
214             } elsif ($self->{level} == XML_ERR_ERROR ||
215             $self->{level} == XML_ERR_FATAL) {
216 974         1535 $level = "error";
217             }
218 974         1377 my $where="";
219 974 100 66     1908 if (defined($self->{file})) {
    100          
220 823         1747 $where="$self->{file}:$self->{line}";
221             } elsif (($self->{domain} == XML_ERR_FROM_PARSER)
222             and
223             $self->{line}) {
224 72         143 $where="Entity: line $self->{line}";
225             }
226 974 50       1849 if ($self->{nodename}) {
227 0         0 $where.=": element ".$self->{nodename};
228             }
229 974 100       2697 $msg.=$where.": " if $where ne "";
230 974         1995 $msg.=$self->domain." ".$level." :";
231 974   50     2331 my $str=$self->{message}||"";
232 974         1568 chomp($str);
233 974         1923 $msg.=" ".$str."\n";
234 974 100 100     2892 if (($self->{domain} == XML_ERR_FROM_XPATH) and
    100          
235             defined($self->{str1})) {
236 20         39 $msg.=$self->{str1}."\n";
237 20         47 $msg.=(" " x $self->{num1})."^\n";
238             } elsif (defined $self->{context}) {
239             # If the error relates to character-encoding problems in the context,
240             # then doing textual operations on it will spew warnings that
241             # XML::LibXML can do nothing to fix. So just disable all such
242             # warnings. This has the pleasing benefit of making the test suite
243             # run warning-free.
244 66     66   576 no warnings 'utf8';
  66         155  
  66         17265  
245 859         1843 my $context = Encode::encode('UTF-8', $self->{context});
246 859         38187 $msg.=$context."\n";
247 859         1945 $context = substr($context,0,$self->{column});
248 859         9837 $context=~s/[^\t]/ /g;
249 859         1849 $msg.=$context."^\n";
250             }
251 974         4118 return $msg;
252             }
253              
254             sub dump {
255 0     0 1   my ($self)=@_;
256 0           require Data::Dumper;
257 0           return Data::Dumper->new([$self],['error'])->Dump;
258             }
259              
260             1;