| App-CamelPKI documentation | Contained in the App-CamelPKI distribution. |
App::CamelPKI::Error - Camel-PKI Error management
use App::CamelPKI::Error;
try {
throw App::CamelPKI::Error::Internal("WRONG_NUMBER_ARGS");
} catch App::CamelPKI::Error with {
warn "Oops, I made a boo-boo!";
};
package My::Facet;
use Class::Facet from => "My::Object",
on_error => \&App::CamelPKI::Error::Privilege::on_facet_error;
This class leverages the Error module, by the excellent Graham Barr and his buddies, to implement error management in Camel-PKI.
Unlike Error, try, with, finally, except and
otherwise symbols are exported by default: no need to say use
Error qw(:try); to import these.
Thrown when a programing issue occurs (for example when not respecting the documented API, using a bad number of arguments, ...).
Thrown when a file issue occurs. The incriminated file name must be passed
as the parameter -IOfile, for example.
throw App::CamelPKI::Error::IO("cannot open file",
-IOfile => $file);
The ->{-errorcode} field will be automatically set with the numerical value of $! (see perlvar) when the error is thrown. The ->{-error} field will be automatically set whith the textual value of this same variable; note that this value depends on the active locale and therefore should not be tested by error catching code.
Thrown each time the owner of a facet, another object or a class with restricted privileges, try to exceeds those which were granted to it. To this effect, the App::CamelPKI::Error::Privilege also defines a on_facet_error function that can be installed as a Class::Facet error handler, as shown in SYNOPSIS.
Thrown when an Camel-PKI database (typically App::CamelPKI::CADB) detects an error at the SQL level, as an invariant violation tentative or an insert of two values for an unique index.
Thrown when a Camel-PKI object or class is in a state which cannot be handled correctly (for example, private key and certificate already present on disk for a non corresponding service), or an asked operation which is no yet or anymore possible to perform (for example when App::CamelPKI::CA ask for a certificate generation when the AC key and certificate are not regulated).
Thrown in case of an error in the communication with an external process (for example failling to start an instance of App::CamelPKI::SysV::Apache).
Thrown when a Camel-PKI mecanism detects an error caused by a bad user action (or a bad usage in a web service client).
| App-CamelPKI documentation | Contained in the App-CamelPKI distribution. |
#!perl -w package App::CamelPKI::Error; use strict; use base "Error";
use Error qw(:try); use base "Error"; use base "Exporter"; our %EXPORT_TAGS=%Error::subs::EXPORT_TAGS; our @EXPORT_OK=map { @$_ } (values %EXPORT_TAGS); our @EXPORT=@{$EXPORT_TAGS{try}}; { no warnings "once"; *import = \&Exporter::import; # Stupid Error.pm redefines its own # ->import() }
package App::CamelPKI::Error::Internal; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error);
package App::CamelPKI::Error::IO; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error); sub new { my $class = shift; local $Error::Depth = $Error::Depth + 1; return $class->SUPER::new(@_, -errorcode => $! + 0, -error => "$!"); }
package App::CamelPKI::Error::Privilege; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error); sub on_facet_error { shift; # Off with the class name throw App::CamelPKI::Error::Privilege(-text => "Facet error", @_); }
package App::CamelPKI::Error::Database; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error);
package App::CamelPKI::Error::State; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error);
package App::CamelPKI::Error::OtherProcess; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error);
package App::CamelPKI::Error::User; use vars qw(@ISA); @ISA=qw(App::CamelPKI::Error);
package App::CamelPKI::Error;
sub new { my $self=shift; splice(@_,0,0,"-text") if (@_ % 2); my %opts=@_; local $Error::Debug = 1; # activates stack traces... local $Carp::MaxEvalLen = 80; # ... but not too long anyway local $Error::Depth = $Error::Depth + 1; $Error::Depth += $opts{-depth} if (exists $opts{-depth}); return $self->Error::new(%opts); }
sub stringify { my ($self) = @_; my $retval = sprintf("%s=%s\n", ref($self), $self->SUPER::stringify); foreach my $k (keys %$self) { next if ($k eq "-text" || $k eq "-stacktrace"); local $@; # if exceptions brakes exceptions... Where do we goes?! my $v = eval { require Data::Dumper; local $Data::Dumper::Indent = $Data::Dumper::Indent = 1; local $Data::Dumper::Terse = $Data::Dumper::Terse = 1; Data::Dumper::Dumper($self->{$k}); } || "<huh?>"; $retval .= " $k => $v"; } $retval .= $self->stacktrace; return $retval; } require My::Tests::Below unless caller(); 1; __END__ use Test::More qw(no_plan); use Test::Group; use App::CamelPKI::Error; test "synopsis: basics" => sub { my $code = My::Tests::Below->pod_code_snippet("synopsis basic"); $code =~ s/warn/our \$foo = /g; eval $code; die $@ if $@; like(our $foo, qr/oops/i); }; skip_next_test unless eval { require Class::Facet }; test "synopsic: Class::Facet integration" => sub { { package My::Object; sub new { bless {}, shift } sub facet { Class::Facet->make("My::Facet", shift) } sub nothing { 1 } } ok(My::Object->new->nothing); my $code = My::Tests::Below->pod_code_snippet("synopsis Class::Facet"); eval $code; die $@ if $@; try { My::Object->new->facet->nothing; fail("should have thrown - Bug in Class::Facet?"); } catch App::CamelPKI::Error::Privilege with { my $E = shift; is($E->{-text}, "Facet error"); is($E->{-method}, "nothing"); }; }; use Errno qw(ENOENT); test "App::CamelPKI::Error::IO and automatic decoration" => sub { my $file = "/no/such_/file"; local *BOGON; open(BOGON, $file); eval My::Tests::Below->pod_code_snippet("App::CamelPKI::Error::IO"); my $E = $@; is($E->{-IOfile}, $file); is($E->{-errorcode}, ENOENT); like($E->{-error}, qr/no such file|aucun fichier/i); }; test "stringify" => sub { my $less = []; my $E = new App::CamelPKI::Error::Internal (-text => "strange schmorpz", -schmorpz => bless { zoinx => [ "is", $less ], less => $less, }, "Schmorpz"); my $string = "$E"; like($E, qr/App::CamelPKI::Error::Internal=strange schmorpz/); like($E, qr/strange schmorpz at /); like($E, qr/-line => \d+/); like($E, qr/bless/); };