Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom error handling #847

Merged
merged 17 commits into from
Sep 7, 2021
13 changes: 8 additions & 5 deletions lib/Zonemaster/Backend/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,25 @@ sub get_db_class {
sub user_exists {
my ( $self, $user ) = @_;

die "username not provided to the method user_exists\n" unless ( $user );
die Zonemaster::Backend::Error::Internal->new( reason => "username not provided to the method user_exists")
unless ( $user );

return $self->user_exists_in_db( $user );
}

sub add_api_user {
my ( $self, $username, $api_key ) = @_;

die "username or api_key not provided to the method add_api_user\n"
unless ( $username && $api_key );
die Zonemaster::Backend::Error::Internal->new( reason => "username or api_key not provided to the method add_api_user")
unless ( $username && $api_key );

die "User already exists\n" if ( $self->user_exists( $username ) );
die Zonemaster::Backend::Error::Conflict->new( message => 'User already exists', data => { username => $username } )
if ( $self->user_exists( $username ) );

my $result = $self->add_api_user_to_db( $username, $api_key );

die "add_api_user_to_db not successful\n" unless ( $result );
die Zonemaster::Backend::Error::Internal->new( reason => "add_api_user_to_db not successful")
unless ( $result );

return $result;
}
Expand Down
32 changes: 26 additions & 6 deletions lib/Zonemaster/Backend/DB/MySQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use DBI qw(:utils);
use JSON::PP;

use Zonemaster::Backend::Validator qw( untaint_ipv6_address );
use Zonemaster::Backend::Errors;

with 'Zonemaster::Backend::DB';

Expand Down Expand Up @@ -128,7 +129,7 @@ sub user_authorized {
sub create_new_batch_job {
my ( $self, $username ) = @_;

my ( $batch_id, $creaton_time ) = $self->dbh->selectrow_array( "
my ( $batch_id, $creation_time ) = $self->dbh->selectrow_array( "
SELECT
batch_id,
batch_jobs.creation_time AS batch_creation_time
Expand All @@ -142,7 +143,8 @@ sub create_new_batch_job {
LIMIT 1
", undef, $username );

die "You can't create a new batch job, job:[$batch_id] started on:[$creaton_time] still running \n" if ( $batch_id );
die Zonemaster::Backend::Error::Conflict->new( message => 'Batch job still running', data => { batch_id => $batch_id, creation_time => $creation_time } )
mattias-p marked this conversation as resolved.
Show resolved Hide resolved
if ( $batch_id );

$self->dbh->do( "INSERT INTO batch_jobs (username) VALUES(?)", undef, $username );
my ( $new_batch_id ) = $self->dbh->{mysql_insertid};
Expand Down Expand Up @@ -228,12 +230,16 @@ sub get_test_params {

my ( $params_json ) = $self->dbh->selectrow_array( "SELECT params FROM test_results WHERE hash_id=?", undef, $test_id );

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $params_json;

my $result;
eval {
$result = decode_json( $params_json );
};

warn "decoding of params_json failed (testi_id: [$test_id]):".Dumper($params_json) if $@;
die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id } )
if $@;

return decode_json( $params_json );
}
Expand All @@ -249,8 +255,22 @@ sub test_results {
my $result;
my ( $hrefs ) = $self->dbh->selectall_hashref( "SELECT id, hash_id, CONVERT_TZ(`creation_time`, \@\@session.time_zone, '+00:00') AS creation_time, params, results FROM test_results WHERE hash_id=?", 'hash_id', undef, $test_id );
$result = $hrefs->{$test_id};
$result->{params} = decode_json( $result->{params} );
$result->{results} = decode_json( $result->{results} );

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $result;

eval {
$result->{params} = decode_json( $result->{params} );

if (defined $result->{results}) {
$result->{results} = decode_json( $result->{results} );
} else {
$result->{results} = [];
}
};

die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id } )
if $@;

return $result;
}
Expand Down Expand Up @@ -370,7 +390,7 @@ sub add_batch_job {
$dbh->{AutoCommit} = 1;
}
else {
die "User $params->{username} not authorized to use batch mode\n";
die Zonemaster::Backend::Error::PermissionDenied->new( message => 'User not authorized to use batch mode', data => { username => $params->{username}} );
}

return $batch_id;
Expand Down
42 changes: 29 additions & 13 deletions lib/Zonemaster/Backend/DB/PostgreSQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use Encode;
use JSON::PP;

use Zonemaster::Backend::DB;
use Zonemaster::Backend::Errors;

with 'Zonemaster::Backend::DB';

Expand Down Expand Up @@ -153,8 +154,8 @@ sub create_new_batch_job {
test_results.progress<>100
LIMIT 1
", undef, $username );

die "You can't create a new batch job, job:[$batch_id] started on:[$creation_time] still running \n" if ( $batch_id );
die Zonemaster::Backend::Error::Conflict->new( message => 'Batch job still running', data => { batch_id => $batch_id, creation_time => $creation_time } )
if ( $batch_id );

my ( $new_batch_id ) =
$dbh->selectrow_array( "INSERT INTO batch_jobs (username) VALUES (?) RETURNING id", undef, $username );
Expand Down Expand Up @@ -207,8 +208,14 @@ sub get_test_params {

my $dbh = $self->dbh;
my ( $params_json ) = $dbh->selectrow_array( "SELECT params FROM test_results WHERE hash_id=?", undef, $test_id );

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $params_json;

eval { $result = decode_json( encode_utf8( $params_json ) ); };
die "$@ \n" if $@;

die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id } )
if $@;

return $result;
}
Expand All @@ -222,27 +229,36 @@ sub test_results {
if ( $results );

my $result;
eval {
my ( $hrefs ) = $dbh->selectall_hashref( "SELECT id, hash_id, creation_time at time zone current_setting('TIMEZONE') at time zone 'UTC' as creation_time, params, results FROM test_results WHERE hash_id=?", 'hash_id', undef, $test_id );
$result = $hrefs->{$test_id};
my ( $hrefs ) = $dbh->selectall_hashref( "SELECT id, hash_id, creation_time at time zone current_setting('TIMEZONE') at time zone 'UTC' as creation_time, params, results FROM test_results WHERE hash_id=?", 'hash_id', undef, $test_id );
$result = $hrefs->{$test_id};

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $result;

eval {
# This workaround is needed to properly handle all versions of perl and the DBD::Pg module
# More details in the zonemaster backend issue #570
if (utf8::is_utf8($result->{params}) ) {
$result->{params} = decode_json( encode_utf8($result->{params}) );
$result->{params} = decode_json( encode_utf8($result->{params}) );
}
else {
$result->{params} = decode_json( $result->{params} );
$result->{params} = decode_json( $result->{params} );
}

if (utf8::is_utf8($result->{results} ) ) {
if (defined $result->{results} ) {
if (utf8::is_utf8($result->{results} ) ) {
$result->{results} = decode_json( encode_utf8($result->{results}) );
}
else {
}
else {
$result->{results} = decode_json( $result->{results} );
}
} else {
$result->{results} = [];
}
};
die "$@ \n" if $@;

die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id })
if $@;

return $result;
}
Expand Down Expand Up @@ -342,7 +358,7 @@ sub add_batch_job {
$dbh->commit();
}
else {
die "User $params->{username} not authorized to use batch mode\n";
die Zonemaster::Backend::Error::PermissionDenied->new( message => 'User not authorized to use batch mode', data => { username => $params->{username}} );
}

return $batch_id;
Expand Down
33 changes: 27 additions & 6 deletions lib/Zonemaster/Backend/DB/SQLite.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use Digest::MD5 qw(md5_hex);
use JSON::PP;
use Log::Any qw( $log );

use Zonemaster::Backend::Errors;

with 'Zonemaster::Backend::DB';

has 'dbh' => (
Expand Down Expand Up @@ -145,7 +147,7 @@ sub user_authorized {
sub create_new_batch_job {
my ( $self, $username ) = @_;

my ( $batch_id, $creaton_time ) = $self->dbh->selectrow_array( "
my ( $batch_id, $creation_time ) = $self->dbh->selectrow_array( "
SELECT
batch_id,
batch_jobs.creation_time AS batch_creation_time
Expand All @@ -158,7 +160,8 @@ sub create_new_batch_job {
LIMIT 1
" );

die "You can't create a new batch job, job:[$batch_id] started on:[$creaton_time] still running \n" if ( $batch_id );
die Zonemaster::Backend::Error::Conflict->new( message => 'Batch job still running', data => { batch_id => $batch_id, creation_time => $creation_time } )
if ( $batch_id );

$self->dbh->do("INSERT INTO batch_jobs (username) VALUES(" . $self->dbh->quote( $username ) . ")" );
my ( $new_batch_id ) = $self->dbh->sqlite_last_insert_rowid;
Expand Down Expand Up @@ -244,12 +247,16 @@ sub get_test_params {

my ( $params_json ) = $self->dbh->selectrow_array( "SELECT params FROM test_results WHERE hash_id=?", undef, $test_id );

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $params_json;

my $result;
eval {
$result = decode_json( $params_json );
};

$log->warn( "decoding of params_json failed (test_id: [$test_id]):".Dumper($params_json) ) if $@;
die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id } )
if $@;

return $result;
}
Expand All @@ -265,8 +272,22 @@ sub test_results {
my $result;
my ( $hrefs ) = $self->dbh->selectall_hashref( "SELECT id, hash_id, creation_time, params, results FROM test_results WHERE hash_id=?", 'hash_id', undef, $test_id );
$result = $hrefs->{$test_id};
$result->{params} = decode_json( $result->{params} );
$result->{results} = decode_json( $result->{results} );

die Zonemaster::Backend::Error::ResourceNotFound->new( message => "Test not found", data => { test_id => $test_id } )
unless defined $result;

eval {
$result->{params} = decode_json( $result->{params} );

if (defined $result->{results}) {
$result->{results} = decode_json( $result->{results} );
} else {
$result->{results} = [];
}
};

die Zonemaster::Backend::Error::JsonError->new( reason => "$@", data => { test_id => $test_id } )
if $@;

return $result;
}
Expand Down Expand Up @@ -363,7 +384,7 @@ sub add_batch_job {
$dbh->{AutoCommit} = 1;
}
else {
die "User $params->{username} not authorized to use batch mode\n";
die Zonemaster::Backend::Error::PermissionDenied->new( message => 'User not authorized to use batch mode', data => { username => $params->{username}} );
}

return $batch_id;
Expand Down
Loading