JanFi86
JanFi86

Reputation: 529

extracting various structured data from hashref

I have a hash, into which error messages are collected. In the hash, __errlist__ is a key and then there is list of one value, which can be string, hash or nested hash like can be seen below:

String:

{'_errlist_' => ['Empty table error - data load failed.']}
        

Hash:

 { '_errlist_' => [
     {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column DWH_TENANT_ID not found in Q. (SQL-HY000) '}]}

Nested hash:

{'_errlist_' => [
     {'message' => 
         {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) '}}]}

or:

{'_errlist_' => [
    {'message' => 
         {'message' => 
             {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) '
                        }}}]}


 

What I came up with is:

 if (defined($RunActSeq->[0]->{'_errlist_'}->[0]->{'message'}->{'message'}->{'message'})){
  $errmsg = $RunActSeq->[0]->{'_errlist_'}->[0]->{'message'}->{'message'}->{'message'};
} elsif (defined($RunActSeq->[0]->{'_errlist_'}->[0])){
  $errmsg = $RunActSeq->[0]->{'_errlist_'}->[0];
} elsif (defined($RunActSeq->[0]->{'_errlist_'}->[0]->{'message'}->{'message'})){
  $errmsg = $RunActSeq->[0]->{'_errlist_'}->[0]->{'message'}->{'message'};
} elsif (defined($RunActSeq->[0]->{'_errlist_'}->[0]->{'message'})  ){
  $errmsg = $RunActSeq->[0]->{'_errlist_'}->[0]->{'message'};
} else {
  $errmsg = "Undefined Error";
}

But I'm still not getting the messages when extracting error messages strings, most of the time I get HASH(0x3c04250) not the message text.

Does anybody pls know how to extract error message more accurately?

Upvotes: 1

Views: 85

Answers (1)

Håkon Hægland
Håkon Hægland

Reputation: 40778

You can try a recursive lookup like this:

use feature qw(say);
use strict;
use warnings;

{
    my @tests = (
        ['Empty table error - data load failed.'],

        [ {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column DWH_TENANT_ID not found in Q. (SQL-HY000) '}],

        [ {'message' =>
           {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) '}}],

        [{'message' =>
          {'message' =>
           {'message' => 'Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) ' }}}],
    );

    for my $i (0..$#tests) {
        my $test = $tests[$i];
        my $hash = { "_errlist_" => $test };
        my $errmsg = extract_err( $hash->{_errlist_}[0] );
        say "Test #$i: $errmsg";
    }
}

sub extract_err {
    my ( $hash ) = @_;

    if (ref $hash eq "HASH") {
        return extract_err( $hash->{message} );
    }
    elsif (!(ref $hash)) {
        return $hash;
    }
    else {
        die "Unexpected reference type: ", ref $hash, "\n";
    }
}

Output:

Test #0: Empty table error - data load failed.
Test #1: Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column DWH_TENANT_ID not found in Q. (SQL-HY000) 
Test #2: Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) 
Test #3: Prepare failed: [Teradata][ODBC Teradata Driver][Teradata Database](-5628)Column not found . (SQL-HY000) 

Upvotes: 2

Related Questions