File Coverage

blib/lib/JSON/Schema/Modern/Error.pm
Criterion Covered Total %
statement 64 65 98.4
branch 5 6 83.3
condition 2 2 100.0
subroutine 20 21 95.2
pod 2 3 66.6
total 93 97 95.8


line stmt bran cond sub pod time code
1 36     36   749 use strict;
  36         101  
  36         1252  
2 36     36   235 use warnings;
  36         101  
  36         1797  
3             package JSON::Schema::Modern::Error;
4             # vim: set ts=8 sts=2 sw=2 tw=100 et :
5             # ABSTRACT: Contains a single error from a JSON Schema evaluation
6              
7             our $VERSION = '0.570';
8              
9 36     36   708 use 5.020;
  36         148  
10 36     36   1459 use Moo;
  36         14602  
  36         354  
11 36     36   18846 use strictures 2;
  36         527  
  36         1815  
12 36     36   8888 use stable 0.031 'postderef';
  36         746  
  36         414  
13 36     36   6891 use experimental 'signatures';
  36         131  
  36         187  
14 36     36   3297 use if "$]" >= 5.022, experimental => 're_strict';
  36         114  
  36         522  
15 36     36   3789 no if "$]" >= 5.031009, feature => 'indirect';
  36         120  
  36         380  
16 36     36   1829 no if "$]" >= 5.033001, feature => 'multidimensional';
  36         105  
  36         285  
17 36     36   1825 no if "$]" >= 5.033006, feature => 'bareword_filehandles';
  36         116  
  36         306  
18 36     36   2381 use Safe::Isa;
  36         1116  
  36         5463  
19 36     36   28553 use JSON::PP ();
  36         532872  
  36         1193  
20 36     36   1213 use MooX::TypeTiny;
  36         671  
  36         412  
21 36     36   53578 use Types::Standard qw(Str Undef InstanceOf Enum);
  36         242448  
  36         310  
22 36     36   86255 use namespace::clean;
  36         337857  
  36         521  
23              
24             use overload
25 36     36   14521 '""' => sub { $_[0]->stringify };
  36     0   103  
  36         316  
  0         0  
26              
27             has [qw(
28             instance_location
29             keyword_location
30             error
31             )] => (
32             is => 'ro',
33             isa => Str,
34             required => 1,
35             );
36              
37             has absolute_keyword_location => (
38             is => 'ro',
39             isa => InstanceOf['Mojo::URL'],
40             coerce => sub { $_[0]->$_isa('Mojo::URL') ? $_[0] : Mojo::URL->new($_[0]) },
41             );
42              
43             has keyword => (
44             is => 'ro',
45             isa => Str|Undef,
46             required => 1,
47             );
48              
49             has exception => (
50             is => 'ro',
51             isa => InstanceOf['JSON::PP::Boolean'],
52             coerce => sub { $_[0] ? JSON::PP::true : JSON::PP::false },
53             );
54              
55             has mode => (
56             is => 'rw',
57             isa => Enum[qw(traverse evaluate)],
58             );
59              
60 9911     9911 1 782132 sub TO_JSON ($self) {
  9911         16486  
  9911         14210  
61             return +{
62             # note that locations are JSON pointers, not uri fragments!
63 9911 100       161689 instanceLocation => $self->instance_location,
64             keywordLocation => $self->keyword_location,
65             !defined($self->absolute_keyword_location) ? ()
66             : ( absoluteKeywordLocation => $self->absolute_keyword_location->to_string ),
67             error => $self->error, # TODO: allow localization
68             };
69             }
70              
71 6     6 0 160 sub stringify ($self) {
  6         10  
  6         9  
72 6 100 100     96 ($self->mode//'evaluate') eq 'traverse'
73             ? '\''.$self->keyword_location.'\': '.$self->error
74             : '\''.$self->instance_location.'\': '.$self->error;
75             }
76              
77 30     30 1 2453 sub dump ($self) {
  30         58  
  30         41  
78 30         127 my $encoder = JSON::MaybeXS->new(utf8 => 0, convert_blessed => 1, canonical => 1, indent => 1, space_after => 1);
79 30 50       630 $encoder->indent_length(2) if $encoder->can('indent_length');
80 30         128 $encoder->encode($self);
81             }
82              
83             1;
84              
85             __END__
86              
87             =pod
88              
89             =encoding UTF-8
90              
91             =for stopwords schema fragmentless
92              
93             =head1 NAME
94              
95             JSON::Schema::Modern::Error - Contains a single error from a JSON Schema evaluation
96              
97             =head1 VERSION
98              
99             version 0.570
100              
101             =head1 SYNOPSIS
102              
103             use JSON::Schema::Modern;
104             my $js = JSON::Schema::Modern->new;
105             my $result = $js->evaluate($data, $schema);
106             my @errors = $result->errors;
107              
108             my $message = $errors[0]->error;
109             my $instance_location = $errors[0]->instance_location;
110              
111             my $errors_encoded = encode_json(\@errors);
112              
113             =head1 DESCRIPTION
114              
115             An instance of this class holds one error from evaluating a JSON Schema with
116             L<JSON::Schema::Modern>.
117              
118             =head1 ATTRIBUTES
119              
120             =head2 keyword
121              
122             The keyword that produced the error; might be C<undef>.
123              
124             =head2 instance_location
125              
126             The path in the instance where the error occurred; encoded as per the JSON Pointer specification
127             (L<RFC 6901|https://datatracker.ietf.org/doc/html/rfc6901>).
128              
129             =head2 keyword_location
130              
131             The schema path taken during evaluation to arrive at the error; encoded as per the JSON Pointer
132             specification (L<RFC 6901|https://datatracker.ietf.org/doc/html/rfc6901>).
133              
134             =head2 absolute_keyword_location
135              
136             The canonical URI or URI reference of the location in the schema where the error occurred; not
137             defined, if there is no base URI for the schema and no C<$ref> was followed. Note that this is not
138             a fragmentless URI in most cases, as the indicated error will occur at a path
139             below the position where the most recent identifier had been declared in the schema. Further, if the
140             schema never declared an absolute base URI (containing a scheme), this URI won't be absolute either.
141              
142             =head2 error
143              
144             The actual error string.
145              
146             =head2 exception
147              
148             Indicates the error's severity is sufficient to stop evaluation.
149              
150             =head1 METHODS
151              
152             =for Pod::Coverage stringify mode
153              
154             =head2 TO_JSON
155              
156             Returns a data structure suitable for serialization. Corresponds to one output unit as specified in
157             L<https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.10.4.2> and
158             L<https://json-schema.org/draft/2019-09/output/schema>, except that C<instanceLocation> and
159             C<keywordLocation> are JSON pointers, B<not> URI fragments. (See the
160             C<strict_basic> L<JSON::Schema::Modern/output_format>
161             if the distinction is important to you.)
162              
163             =head2 dump
164              
165             Returns a JSON string representing the error object, according to
166             the L<specification|https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.10>.
167              
168             =for stopwords OpenAPI
169              
170             =head1 SUPPORT
171              
172             Bugs may be submitted through L<https://github.com/karenetheridge/JSON-Schema-Modern/issues>.
173              
174             I am also usually active on irc, as 'ether' at C<irc.perl.org> and C<irc.libera.chat>.
175              
176             You can also find me on the L<JSON Schema Slack server|https://json-schema.slack.com> and L<OpenAPI Slack
177             server|https://open-api.slack.com>, which are also great resources for finding help.
178              
179             =head1 AUTHOR
180              
181             Karen Etheridge <ether@cpan.org>
182              
183             =head1 COPYRIGHT AND LICENCE
184              
185             This software is copyright (c) 2020 by Karen Etheridge.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut