File Coverage

blib/lib/LINQ/Exception.pm
Criterion Covered Total %
statement 75 75 100.0
branch 6 6 100.0
condition n/a
subroutine 29 29 100.0
pod 3 3 100.0
total 113 113 100.0


line stmt bran cond sub pod time code
1 39     39   2906 use 5.006;
  39         224  
2 39     39   279 use strict;
  39         92  
  39         1021  
3 39     39   228 use warnings;
  39         125  
  39         3832  
4              
5             if ( $] < 5.010000 ) {
6             require UNIVERSAL::DOES;
7             }
8              
9             {
10              
11             package LINQ::Exception;
12             our $AUTHORITY = 'cpan:TOBYINK';
13             our $VERSION = '0.002';
14            
15 39     39   9683 use Class::Tiny qw( package file line );
  39         35733  
  39         273  
16 39     39   20051 use overload q[""] => sub { shift->to_string };
  39     60   138  
  39         452  
  60         20425  
17            
18 2     2 1 3574 sub message { "An error occurred" }
19            
20             sub to_string {
21 60     60 1 117 my $self = shift;
22 60         935 sprintf(
23             "%s at %s line %d.\n",
24             $self->message,
25             $self->file,
26             $self->line,
27             );
28             }
29            
30             sub throw {
31 69     69 1 22395 my $class = shift;
32            
33 69         154 my ( $level, %caller ) = 0;
34 69         749 $level++ until caller( $level ) !~ /\ALINQx?(::|\z)/;
35 69         636 @caller{qw/ package file line /} = caller( $level );
36            
37 69         589 die( $class->new( %caller, @_ ) );
38             }
39             }
40              
41             {
42              
43             package LINQ::Exception::Unimplemented;
44             our $AUTHORITY = 'cpan:TOBYINK';
45             our $VERSION = '0.002';
46 39     39   11681 use parent -norequire, qw( LINQ::Exception );
  39         102  
  39         419  
47 39     39   2211 use Class::Tiny qw( method );
  39         83  
  39         172  
48            
49             sub message {
50 4     4   7 my $self = shift;
51 4         113 my $meth = $self->method;
52 4         101 "Method $meth is unimplemented";
53             }
54             }
55              
56             {
57              
58             package LINQ::Exception::InternalError;
59             our $AUTHORITY = 'cpan:TOBYINK';
60             our $VERSION = '0.002';
61 39     39   11791 use parent -norequire, qw( LINQ::Exception );
  39         108  
  39         197  
62 39     39   2128 use Class::Tiny qw( message );
  39         129  
  39         164  
63             }
64              
65             {
66              
67             package LINQ::Exception::CallerError;
68             our $AUTHORITY = 'cpan:TOBYINK';
69             our $VERSION = '0.002';
70 39     39   9463 use parent -norequire, qw( LINQ::Exception );
  39         97  
  39         256  
71 39     39   1758 use Class::Tiny qw( message );
  39         86  
  39         180  
72            
73             sub BUILD {
74 28     28   2875 my $self = shift;
75 28 100       643 'LINQ::Exception::InternalError'
76             ->throw( message => 'Required attribute "message" not defined' )
77             unless defined $self->message;
78             }
79             }
80              
81             {
82              
83             package LINQ::Exception::CollectionError;
84             our $AUTHORITY = 'cpan:TOBYINK';
85             our $VERSION = '0.002';
86 39     39   10558 use parent -norequire, qw( LINQ::Exception );
  39         99  
  39         192  
87 39     39   1963 use Class::Tiny qw( collection );
  39         83  
  39         146  
88            
89             sub BUILD {
90 31     31   4351 my $self = shift;
91 31 100       747 'LINQ::Exception::InternalError'
92             ->throw( message => 'Required attribute "collection" not defined' )
93             unless defined $self->collection;
94             }
95             }
96              
97             {
98              
99             package LINQ::Exception::NotFound;
100             our $AUTHORITY = 'cpan:TOBYINK';
101             our $VERSION = '0.002';
102 39     39   11463 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         95  
  39         222  
103 10     10   191 sub message { "Item not found" }
104             }
105              
106             {
107              
108             package LINQ::Exception::MultipleFound;
109             our $AUTHORITY = 'cpan:TOBYINK';
110             our $VERSION = '0.002';
111 39     39   3989 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         122  
  39         205  
112 39     39   1961 use Class::Tiny qw( found );
  39         86  
  39         177  
113 2     2   63 sub message { "Item not found" }
114             }
115              
116             {
117              
118             package LINQ::Exception::Cast;
119             our $AUTHORITY = 'cpan:TOBYINK';
120             our $VERSION = '0.002';
121 39     39   9586 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         96  
  39         188  
122 39     39   1788 use Class::Tiny qw( type );
  39         79  
  39         198  
123            
124             sub message {
125 4     4   69 my $type = shift->type;
126 4         49 "Not all elements in the collection could be cast to $type";
127             }
128            
129             sub BUILD {
130 5     5   136 my $self = shift;
131 5 100       89 'LINQ::Exception::InternalError'
132             ->throw( message => 'Required attribute "type" not defined' )
133             unless defined $self->type;
134             }
135             }
136              
137             1;
138              
139             =pod
140              
141             =encoding utf-8
142              
143             =head1 NAME
144              
145             LINQ::Exception - exceptions thrown by LINQ
146              
147             =head1 DESCRIPTION
148              
149             When LINQ encounters an error, it doesn't just C<die> with a string, but throws
150             an exception object which can be caught with C<eval>, L<Try::Tiny>, or
151             L<Syntax::Keyword::Try>.
152              
153             These objects overload stringification, so if they are not caught and dealt
154             with, you'll get a sensible error message printed.
155              
156             =head1 EXCEPTION TYPES
157              
158             =head2 LINQ::Exception
159              
160             This is the base class for all LINQ exceptions.
161              
162             use LINQ qw( LINQ );
163             use Syntax::Keyword::Try qw( try :experimental );
164            
165             try {
166             my $collection = LINQ [ 1, 2, 3 ];
167             my $item = $collection->element_at( 10 );
168             }
169             catch ( $e isa LINQ::Exception ) {
170             printf(
171             "Got error: %s at %s (%s line %d)\n",
172             $e->message,
173             $e->package,
174             $e->file,
175             $e->line,
176             );
177             }
178              
179             The class provides C<message>, C<package>, C<file>, and C<line> methods to
180             get details of the error, as well as a C<to_string> method which provides the
181             message, package, file, and line as one combined string.
182              
183             There is a class method C<throw> which instantiates a new object and dies.
184              
185             'LINQ::Exception'->throw;
186              
187             LINQ::Exception is never directly thrown by LINQ, but subclasses of it are.
188              
189             =begin trustme
190              
191             =item throw
192              
193             =item message
194              
195             =item file
196              
197             =item line
198              
199             =item package
200              
201             =item to_string
202              
203             =end trustme
204              
205             =head2 LINQ::Exception::Unimplemented
206              
207             A subclass of LINQ::Exception thrown when you call a method or feature which
208             is not implemented for the collection you call it on.
209              
210             =head2 LINQ::Exception::InternalError
211              
212             A subclass of LINQ::Exception thrown when an internal error is encountered in
213             LINQ, not caused by the caller.
214              
215             =head2 LINQ::Exception::CallerError
216              
217             A subclass of LINQ::Exception thrown when the caller of a method has called it
218             incorrectly. For example, if a method is called which expects a coderef as a
219             parameter, but is given a string.
220              
221             =head2 LINQ::Exception::CollectionError
222              
223             A subclass of LINQ::Exception thrown when a method you've called cannot be
224             fulfilled by the collection you've called it on. For example, you've asked to
225             fetch the third item in a collection containing only two items.
226              
227             The exception has a C<collection> attribute which returns the collection which
228             generated the error.
229              
230             =head2 LINQ::Exception::NotFound
231              
232             A subclass of LINQ::Exception::CollectionError thrown when trying to access an
233             item in a collection which cannot be found.
234              
235             =head2 LINQ::Exception::MultipleFound
236              
237             A subclass of LINQ::Exception::CollectionError thrown when trying to access a
238             single item in a collection when multiple items are found.
239              
240             =head2 LINQ::Exception::Cast
241              
242             A subclass of LINQ::Exception::CollectionError thrown when trying to cast all
243             items in a collection to a type, but this fails for one or more items.
244              
245             =head1 BUGS
246              
247             Please report any bugs to
248             L<http://rt.cpan.org/Dist/Display.html?Queue=LINQ>.
249              
250             =head1 SEE ALSO
251              
252             L<LINQ>.
253              
254             =head1 AUTHOR
255              
256             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
257              
258             =head1 COPYRIGHT AND LICENCE
259              
260             This software is copyright (c) 2014, 2021 by Toby Inkster.
261              
262             This is free software; you can redistribute it and/or modify it under
263             the same terms as the Perl 5 programming language system itself.
264              
265             =head1 DISCLAIMER OF WARRANTIES
266              
267             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
268             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
269             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.