| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Error::TypeTiny; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 299 |  |  | 299 |  | 8326 | use 5.008001; | 
|  | 299 |  |  |  |  | 1151 |  | 
| 4 | 299 |  |  | 299 |  | 2523 | use strict; | 
|  | 299 |  |  |  |  | 668 |  | 
|  | 299 |  |  |  |  | 7226 |  | 
| 5 | 299 |  |  | 299 |  | 1690 | use warnings; | 
|  | 299 |  |  |  |  | 679 |  | 
|  | 299 |  |  |  |  | 13974 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | BEGIN { | 
| 8 | 299 |  |  | 299 |  | 1210 | $Error::TypeTiny::AUTHORITY = 'cpan:TOBYINK'; | 
| 9 | 299 |  |  |  |  | 259337 | $Error::TypeTiny::VERSION   = '2.003_000'; | 
| 10 |  |  |  |  |  |  | } | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | $Error::TypeTiny::VERSION =~ tr/_//d; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | require Type::Tiny; | 
| 15 |  |  |  |  |  |  | __PACKAGE__->Type::Tiny::_install_overloads( | 
| 16 | 750 |  |  | 750 |  | 231195 | q[""]   => sub { $_[0]->to_string }, | 
| 17 | 1648 |  |  | 1648 |  | 12203 | q[bool] => sub { 1 }, | 
| 18 |  |  |  |  |  |  | ); | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | require Carp; | 
| 21 |  |  |  |  |  |  | *CarpInternal = \%Carp::CarpInternal; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | our %CarpInternal; | 
| 24 |  |  |  |  |  |  | $CarpInternal{$_}++ for @Type::Tiny::InternalPackages; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub new { | 
| 27 | 873 |  |  | 873 | 1 | 1648 | my $class  = shift; | 
| 28 | 873 | 50 |  |  |  | 4587 | my %params = ( @_ == 1 ) ? %{ $_[0] } : @_; | 
|  | 0 |  |  |  |  | 0 |  | 
| 29 | 873 |  |  |  |  | 3572 | return bless \%params, $class; | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | sub throw { | 
| 33 | 450 |  |  | 450 | 1 | 29859 | my $next = $_[0]->can( 'throw_cb' ); | 
| 34 | 450 |  |  |  |  | 1341 | splice( @_, 1, 0, undef ); | 
| 35 | 450 |  |  |  |  | 1255 | goto $next; | 
| 36 |  |  |  |  |  |  | } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | sub throw_cb { | 
| 39 | 872 |  |  | 872 | 1 | 2069 | my $class = shift; | 
| 40 | 872 |  |  |  |  | 1427 | my $callback = shift; | 
| 41 |  |  |  |  |  |  |  | 
| 42 | 872 |  |  |  |  | 1896 | my ( $level, @caller, %ctxt ) = 0; | 
| 43 | 872 |  |  |  |  | 1444 | while ( | 
| 44 |  |  |  |  |  |  | do { | 
| 45 | 2445 |  |  |  |  | 4176 | my $caller = caller $level; | 
| 46 | 2445 | 50 |  |  |  | 9574 | defined $caller and $CarpInternal{$caller}; | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  | ) | 
| 49 |  |  |  |  |  |  | { | 
| 50 | 1573 |  |  |  |  | 2359 | $level++; | 
| 51 |  |  |  |  |  |  | } | 
| 52 | 872 | 100 | 100 |  |  | 9210 | if ( ( ( caller( $level - 1 ) )[1] || "" ) =~ | 
| 53 |  |  |  |  |  |  | /^(?:parameter validation for|exportable function) '(.+?)'$/ ) | 
| 54 |  |  |  |  |  |  | { | 
| 55 | 640 |  |  |  |  | 4046 | my ( $pkg, $func ) = ( $1 =~ m{^(.+)::(\w+)$} ); | 
| 56 | 640 | 100 | 50 |  |  | 2587 | $level++ if caller( $level ) eq ( $pkg || "" ); | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | # Moo's Method::Generate::Constructor puts an eval in the stack trace, | 
| 60 |  |  |  |  |  |  | # that is useless for debugging, so show the stack frame one above. | 
| 61 | 872 | 50 | 33 |  |  | 6415 | $level++ | 
| 62 |  |  |  |  |  |  | if ( | 
| 63 |  |  |  |  |  |  | ( caller( $level ) )[1] =~ /^\(eval \d+\)$/ | 
| 64 |  |  |  |  |  |  | and ( caller( $level ) )[3] eq '(eval)'    # (caller())[3] is $subroutine | 
| 65 |  |  |  |  |  |  | ); | 
| 66 | 872 |  |  |  |  | 5209 | @ctxt{qw/ package file line /} = caller( $level ); | 
| 67 |  |  |  |  |  |  |  | 
| 68 | 872 |  |  |  |  | 1925 | my $stack = undef; | 
| 69 | 872 | 100 |  |  |  | 2034 | if ( our $StackTrace ) { | 
| 70 | 1 |  |  |  |  | 5 | require Devel::StackTrace; | 
| 71 | 1 |  |  |  |  | 23 | $stack = "Devel::StackTrace"->new( | 
| 72 |  |  |  |  |  |  | ignore_package => [ keys %CarpInternal ], | 
| 73 |  |  |  |  |  |  | ); | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 872 |  |  |  |  | 3977 | our $LastError = $class->new( | 
| 77 |  |  |  |  |  |  | context     => \%ctxt, | 
| 78 |  |  |  |  |  |  | stack_trace => $stack, | 
| 79 |  |  |  |  |  |  | @_, | 
| 80 |  |  |  |  |  |  | ); | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 872 | 100 |  |  |  | 7903 | $callback ? $callback->( $LastError ) : die( $LastError ); | 
| 83 |  |  |  |  |  |  | } #/ sub throw | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 769 |  | 66 | 769 | 1 | 7670 | sub message     { $_[0]{message} ||= $_[0]->_build_message } | 
| 86 | 757 |  |  | 757 | 1 | 2905 | sub context     { $_[0]{context} } | 
| 87 | 3 |  |  | 3 | 1 | 2627 | sub stack_trace { $_[0]{stack_trace} } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub to_string { | 
| 90 | 403 |  |  | 403 | 1 | 976 | my $e = shift; | 
| 91 | 403 |  |  |  |  | 1265 | my $c = $e->context; | 
| 92 | 403 |  |  |  |  | 1054 | my $m = $e->message; | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | $m =~ /\n\z/s | 
| 95 |  |  |  |  |  |  | ? $m | 
| 96 |  |  |  |  |  |  | : $c ? sprintf( | 
| 97 |  |  |  |  |  |  | "%s at %s line %s.\n", $m, $c->{file} || 'file?', | 
| 98 | 403 | 50 | 50 |  |  | 5562 | $c->{line} || 'NaN' | 
|  |  | 50 | 50 |  |  |  |  | 
| 99 |  |  |  |  |  |  | ) | 
| 100 |  |  |  |  |  |  | : sprintf( "%s\n", $m ); | 
| 101 |  |  |  |  |  |  | } #/ sub to_string | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | sub _build_message { | 
| 104 | 1 |  |  | 1 |  | 6 | return 'An exception has occurred'; | 
| 105 |  |  |  |  |  |  | } | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | sub croak { | 
| 108 | 148 |  |  | 148 | 1 | 483 | my ( $fmt, @args ) = @_; | 
| 109 | 148 |  |  |  |  | 813 | @_ = ( | 
| 110 |  |  |  |  |  |  | __PACKAGE__, | 
| 111 |  |  |  |  |  |  | message => sprintf( $fmt, @args ), | 
| 112 |  |  |  |  |  |  | ); | 
| 113 | 148 |  |  |  |  | 587 | goto \&throw; | 
| 114 |  |  |  |  |  |  | } | 
| 115 |  |  |  |  |  |  |  | 
| 116 |  |  |  |  |  |  | 1; | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | __END__ | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | =pod | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | =encoding utf-8 | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | =head1 NAME | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | Error::TypeTiny - exceptions for Type::Tiny and friends | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | use Data::Dumper; | 
| 131 |  |  |  |  |  |  | use Try::Tiny; | 
| 132 |  |  |  |  |  |  | use Types::Standard qw(Str); | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | try { | 
| 135 |  |  |  |  |  |  | Str->assert_valid(undef); | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  | catch { | 
| 138 |  |  |  |  |  |  | my $exception = shift; | 
| 139 |  |  |  |  |  |  | warn "Encountered Error: $exception"; | 
| 140 |  |  |  |  |  |  | warn Dumper($exception->explain) | 
| 141 |  |  |  |  |  |  | if $exception->isa("Error::TypeTiny::Assertion"); | 
| 142 |  |  |  |  |  |  | }; | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | =head1 STATUS | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | This module is covered by the | 
| 147 |  |  |  |  |  |  | L<Type-Tiny stability policy|Type::Tiny::Manual::Policies/"STABILITY">. | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | When Type::Tiny and its related modules encounter an error, they throw an | 
| 152 |  |  |  |  |  |  | exception object. These exception objects inherit from Error::TypeTiny. | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | =head2 Constructors | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | =over | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | =item C<< new(%attributes) >> | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | Moose-style constructor function. | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | =item C<< throw(%attributes) >> | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | Constructs an exception and passes it to C<die>. | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | Automatically populates C<context> and C<stack_trace> if appropriate. | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | =item C<< throw_cb($callback, %attributes) >> | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | Constructs an exception and passes it to C<< $callback >> which should | 
| 171 |  |  |  |  |  |  | be a coderef; if undef, uses C<die>. | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | Automatically populates C<context> and C<stack_trace> if appropriate. | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | =back | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | =head2 Attributes | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | =over | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | =item C<message> | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | The error message. | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =item C<context> | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | Hashref containing the package, file and line that generated the error. | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | =item C<stack_trace> | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | A more complete stack trace. This feature requires L<Devel::StackTrace>; | 
| 192 |  |  |  |  |  |  | use the C<< $StackTrace >> package variable to switch it on. | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | =back | 
| 195 |  |  |  |  |  |  |  | 
| 196 |  |  |  |  |  |  | =head2 Methods | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | =over | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | =item C<to_string> | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  | Returns the message, followed by the context if it is set. | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | =back | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  | =head2 Functions | 
| 207 |  |  |  |  |  |  |  | 
| 208 |  |  |  |  |  |  | =over | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | =item C<< Error::TypeTiny::croak($format, @args) >> | 
| 211 |  |  |  |  |  |  |  | 
| 212 |  |  |  |  |  |  | Functional-style shortcut to C<throw> method. Takes an C<sprintf>-style | 
| 213 |  |  |  |  |  |  | format string and optional arguments to construct the C<message>. | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | =back | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | =head2 Overloading | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | =over | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | =item * | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | Stringification is overloaded to call C<to_string>. | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | =back | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =head2 Package Variables | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | =over | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | =item C<< %Carp::CarpInternal >> | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | Error::TypeTiny honours this package variable from L<Carp>. | 
| 234 |  |  |  |  |  |  | (C< %Error::TypeTiny::CarpInternal> is an alias for it.) | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =item C<< $Error::TypeTiny::StackTrace >> | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | Boolean to toggle stack trace generation. | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | =item C<< $Error::TypeTiny::LastError >> | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | A reference to the last exception object thrown. | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | =back | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | =head1 CAVEATS | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | Although Error::TypeTiny objects are thrown for errors produced by | 
| 249 |  |  |  |  |  |  | Type::Tiny, that doesn't mean every time you use Type::Tiny you'll get | 
| 250 |  |  |  |  |  |  | Error::TypeTinys whenever you want. | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | For example, if you use a Type::Tiny type constraint in a Moose attribute, | 
| 253 |  |  |  |  |  |  | Moose will not call the constraint's C<assert_valid> method (which throws | 
| 254 |  |  |  |  |  |  | an exception). Instead it will call C<check> and C<get_message> (which do | 
| 255 |  |  |  |  |  |  | not), and will C<confess> an error message of its own. (The C<< $LastError >> | 
| 256 |  |  |  |  |  |  | package variable may save your bacon.) | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | =head1 BUGS | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | Please report any bugs to | 
| 261 |  |  |  |  |  |  | L<https://github.com/tobyink/p5-type-tiny/issues>. | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | L<Error::TypeTiny::Assertion>, | 
| 266 |  |  |  |  |  |  | L<Error::TypeTiny::WrongNumberOfParameters>. | 
| 267 |  |  |  |  |  |  |  | 
| 268 |  |  |  |  |  |  | L<Try::Tiny>, L<Try::Tiny::ByClass>. | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | =head1 AUTHOR | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | Toby Inkster E<lt>tobyink@cpan.orgE<gt>. | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENCE | 
| 275 |  |  |  |  |  |  |  | 
| 276 |  |  |  |  |  |  | This software is copyright (c) 2013-2014, 2017-2023 by Toby Inkster. | 
| 277 |  |  |  |  |  |  |  | 
| 278 |  |  |  |  |  |  | This is free software; you can redistribute it and/or modify it under | 
| 279 |  |  |  |  |  |  | the same terms as the Perl 5 programming language system itself. | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | =head1 DISCLAIMER OF WARRANTIES | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | 
| 284 |  |  |  |  |  |  | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | 
| 285 |  |  |  |  |  |  | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |