| Net-SSLeay-OO documentation | Contained in the Net-SSLeay-OO distribution. |
Net::SSLeay::OO::Error - encapsulated SSLeay errors
use Scalar::Util qw(blessed);
eval {
$ctx->use_PrivateKey_file($filename, FILETYPE_PEM);
};
my $error = $@;
if (blessed $error and
( $error->error_code == 0x0B080074 or
$error->reason_string =~ /key.*mismatch/i ) ) {
# deal with some known error condition differently..
die "Private key file mismatches certificate file, did "
."you update both settings?";
}
elsif ($error) {
die $error;
}
# if you need to manually check for errors ever
use Net::SSLeay::OO::Error qw(die_if_ssl_error ssl_error_pending);
die_if_ssl_error("Initialization");
Unlike Net::SSLeay, with Net::SSLeay::OO functions, if an error
occurs in a low level library an exception is raised via die.
OpenSSL has an 'error queue', which normally represents something like a stack trace indicating the context of the error. The first error will be the "deepest" error and usually has the most relevant error message. To represent this, the Net::SSLeay::OO::Error object has a next property, which represents a level further up the exception heirarchy.
The following methods are defined (some via Moose attributes):
Returns the error string from OpenSSL.
Returns the error string, turned into a marginally more user-friendly message. Also available as the overloaded '""' operator (ie, when interpreted as a string you will get a message)
A fixed error code corresponding to the error.
The human-readable part, or (apparently) "system lib" if the error is part of a stack trace.
Where the error occurred, or where this part of the stack trace applies.
The next (shallower) Net::SSLeay::OO::Error object, corresponding to the next level up the stack trace.
The caller-supplied message that this error will be prefixed with. If
this is a single word (no whitespace) then it will be printed as
During `$message':.
These functions are available for export.
This is similar to Net::SSLeay's function of the same name, except;
The entire error queue is cleared, and wrapped into a single chain of exception objects
The message is parceled to be hopefully a little more human-readable.
Here is an example, an error raised during the test suite script t/03-ssl.t:
During `use_certificate_file': OpenSSL error 02001002: No such file or directory during fopen (system library)
then 20074002: trace: FILE_CTRL (BIO routines)
then 140c8002: trace: SSL_use_certificate_file (SSL routines)
The function was called as:
die_if_ssl_error("use_certificate_file")
The strings returned from OpenSSL as a "human readable" error messages were:
error:02001002:system library:fopen:No such file or directory error:20074002:BIO routines:FILE_CTRL:system lib error:140C8002:SSL routines:SSL_use_certificate_file:system lib
Returns a non-zero integer if there is an error pending. To fetch it, just create a new Net::SSLeay::OO::Error object.
Sam Vilain, samv@cpan.org
Copyright (C) 2009 NZ Registry Services
This program is free software: you can redistribute it and/or modify it under the terms of the Artistic License 2.0 or later. You should have received a copy of the Artistic License the file COPYING.txt. If not, see <http://www.perlfoundation.org/artistic_license_2_0>
| Net-SSLeay-OO documentation | Contained in the Net-SSLeay-OO distribution. |
package Net::SSLeay::OO::Error; use Net::SSLeay; use Moose; has 'err' => isa => 'Int', is => 'ro', required => 1, default => sub { Net::SSLeay::ERR_get_error or die "no OpenSSL error to get"; }; sub ssl_error_pending { Net::SSLeay::ERR_peek_error; } has 'error_code' => isa => "Int", is => "ro", ; has 'library_name' => isa => "Str", is => "ro", ; has 'function_name' => isa => "Str", is => "ro", ; has 'reason_string' => isa => "Str", is => "ro", ; has 'next' => isa => __PACKAGE__, is => "ro", ; sub BUILD { my $self = shift; my $ssl_error = $self->error_string; ( undef, my @fields ) = split ":", $ssl_error, 5; $self->{error_code} ||= hex( shift @fields ); $self->{library_name} ||= shift @fields; $self->{function_name} ||= shift @fields; $self->{reason_string} ||= shift @fields; # OpenSSL throws an entire stack backtrace, so capture all the # outstanding SSL errors and chain them off this one. if (ssl_error_pending) { $self->{next} = ( ref $self )->new(); } } has 'message' => isa => "Str", is => "rw", ; sub die_if_ssl_error { my $message = shift; if (ssl_error_pending) { die __PACKAGE__->new( message => $message ); } } sub as_string { my $self = shift; my $message = $self->message; if ($message) { unless ( $message =~ / / ) { $message = "During `$message'"; } $message .= ": "; } else { $message = ""; } my $reason_string = $self->reason_string; my $result = do { if ( $reason_string eq "system lib" ) { # FIXME: lang sprintf( "%s%.8x: trace: %s (%s)", $message, $self->error_code, $self->function_name, $self->library_name ); } else { sprintf("%sOpenSSL error %.8x: %s during %s (%s)", $message, $self->error_code, $self->reason_string, $self->function_name, $self->library_name ); } }; if ( $self->next ) { $result .= "\n" . " then " . $self->next->as_string; } if ( $result =~ m{\n} and $result !~ m{\n\Z} ) { $result .= "\n"; } $result; } use overload '""' => \&as_string, ; use Sub::Exporter -setup => { exports => [qw(die_if_ssl_error ssl_error_pending)], }; use Net::SSLeay::OO::Functions sub { my $code = shift; sub { my $self = shift; $code->( $self->err, @_ ); } }; 1; __END__
# Local Variables: # mode:cperl # indent-tabs-mode: t # cperl-continued-statement-offset: 8 # cperl-brace-offset: 0 # cperl-close-paren-offset: 0 # cperl-continued-brace-offset: 0 # cperl-continued-statement-offset: 8 # cperl-extra-newline-before-brace: nil # cperl-indent-level: 8 # cperl-indent-parens-as-block: t # cperl-indent-wrt-brace: nil # cperl-label-offset: -8 # cperl-merge-trailing-else: t # End: # vim: filetype=perl:noexpandtab:ts=3:sw=3