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   2804 use 5.006;
  39         136  
2 39     39   205 use strict;
  39         93  
  39         925  
3 39     39   192 use warnings;
  39         119  
  39         3843  
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.001';
14            
15 39     39   9897 use Class::Tiny qw( package file line );
  39         34967  
  39         243  
16 39     39   20547 use overload q[""] => sub { shift->to_string };
  39     60   117  
  39         402  
  60         17875  
17            
18 2     2 1 3134 sub message { "An error occurred" }
19            
20             sub to_string {
21 60     60 1 115 my $self = shift;
22 60         794 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 17921 my $class = shift;
32            
33 69         152 my ( $level, %caller ) = 0;
34 69         734 $level++ until caller( $level ) !~ /\ALINQx?(::|\z)/;
35 69         603 @caller{qw/ package file line /} = caller( $level );
36            
37 69         555 die( $class->new( %caller, @_ ) );
38             }
39             }
40              
41             {
42              
43             package LINQ::Exception::Unimplemented;
44             our $AUTHORITY = 'cpan:TOBYINK';
45             our $VERSION = '0.001';
46 39     39   11814 use parent -norequire, qw( LINQ::Exception );
  39         141  
  39         382  
47 39     39   2423 use Class::Tiny qw( method );
  39         113  
  39         156  
48            
49             sub message {
50 4     4   8 my $self = shift;
51 4         102 my $meth = $self->method;
52 4         100 "Method $meth is unimplemented";
53             }
54             }
55              
56             {
57              
58             package LINQ::Exception::InternalError;
59             our $AUTHORITY = 'cpan:TOBYINK';
60             our $VERSION = '0.001';
61 39     39   11928 use parent -norequire, qw( LINQ::Exception );
  39         104  
  39         197  
62 39     39   2079 use Class::Tiny qw( message );
  39         108  
  39         161  
63             }
64              
65             {
66              
67             package LINQ::Exception::CallerError;
68             our $AUTHORITY = 'cpan:TOBYINK';
69             our $VERSION = '0.001';
70 39     39   9624 use parent -norequire, qw( LINQ::Exception );
  39         94  
  39         203  
71 39     39   1883 use Class::Tiny qw( message );
  39         90  
  39         132  
72            
73             sub BUILD {
74 28     28   2769 my $self = shift;
75 28 100       622 '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.001';
86 39     39   10628 use parent -norequire, qw( LINQ::Exception );
  39         99  
  39         202  
87 39     39   1992 use Class::Tiny qw( collection );
  39         79  
  39         160  
88            
89             sub BUILD {
90 31     31   4446 my $self = shift;
91 31 100       796 '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.001';
102 39     39   11555 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         94  
  39         206  
103 10     10   223 sub message { "Item not found" }
104             }
105              
106             {
107              
108             package LINQ::Exception::MultipleFound;
109             our $AUTHORITY = 'cpan:TOBYINK';
110             our $VERSION = '0.001';
111 39     39   3934 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         133  
  39         215  
112 39     39   1960 use Class::Tiny qw( found );
  39         85  
  39         162  
113 2     2   73 sub message { "Item not found" }
114             }
115              
116             {
117              
118             package LINQ::Exception::Cast;
119             our $AUTHORITY = 'cpan:TOBYINK';
120             our $VERSION = '0.001';
121 39     39   10394 use parent -norequire, qw( LINQ::Exception::CollectionError );
  39         92  
  39         196  
122 39     39   1891 use Class::Tiny qw( type );
  39         106  
  39         210  
123            
124             sub message {
125 4     4   75 my $type = shift->type;
126 4         44 "Not all elements in the collection could be cast to $type";
127             }
128            
129             sub BUILD {
130 5     5   132 my $self = shift;
131 5 100       84 '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.