in reply to eval doesn't work under tkx

I'm absolutely sure that your eval error is not related to the Tkx (as Corion said). Can you post a bit more code (ideally it must be program which produce same error: Access database with only one table, one button on Tkx and SQL query which produce table already exists error)?

Replies are listed 'Best First'.
Re^2: eval doesn't work under tkx
by nyj (Novice) on Jul 16, 2010 at 06:16 UTC
    I can't put all the code up here - its confidential. But the full code of the sub in question is
    sub runQueries { my $LogFilePath = $ENV{"DATALOADFILEROOT"}."/files/"; my ($thingToDo, $fileHandle, $queriesToRunRef, $queryCodeRef, $dbh +) = @_; # 'queries' is a list of queries we need to run in a certain order # 'queryCode' is a hash list of queries, keyed on query name. my @queries = @$queriesToRunRef; my %queryCode = %$queryCodeRef; my $sqlStatement = ""; my $sth; foreach my $query(@queries) { print $fileHandle "next query is $query\n"; if (defined $queryCode{$query}) { print "1\n"; my $queryLogFile = $LogFilePath . $query; my $sqlSuccess = 0; print "2\n"; if (defined $queryFiles{$query}) { print $fileHandle "writing to file - $queryLogFile\n"; open(queryLog, ">$queryLogFile") or return "Couldn't o +pen $logFilePath . $queryLogFile - $!"; } print "3\n"; my $sqlStatement = $queryCode{$query}; my $rowCount = 0; print $fileHandle "code - $sqlStatement\n"; # We put these next statements into a loop because we migh +t encounter an error # we can recover from. If so, the 'eval' will catch it a +nd throw it to 'if ($@)' while ($sqlSuccess == 0) { print "4\n"; eval { print "5\n"; #$dbh->{RaiseError} = 1; print "6\n"; $sth = $dbh->prepare($sqlStatement); print "7\n"; $sth->execute(); print "8\n"; print $fileHandle "rows affected - " . $sth->rows +. "\n"; #my $result = $sth->fetchall_arrayref({}); while (my @row=$sth->fetchrow_array()) { if (defined $queryFiles{$query}) { print queryLog "@row\n"; } $rowCount++; } $sqlSuccess = 1; }; if ($@) { print $fileHandle "caught error $@\n"; my $errString = $@; print $fileHandle "here err string is |$errString| +\n"; if ($errString =~ m|Table '(.*)' already exists|) { print $fileHandle "got to here\n"; my $sql = "drop table " . $1; my $drop = $dbh->prepare($sql); $drop->execute(); } else { return "Error found - $errString"; } } } if ($rowCount > 0 && (defined $queryFiles{$query}) && $que +ryFiles{$query} eq "stop") { return "query '$query' wrote $rowCount rows - this nee +ds investigating\n"; } if (defined $queryFiles{$query}) { print $fileHandle "Wrote $rowCount rows\n"; close querylog; } } else { print $fileHandle "******* NO CODE FOR THIS KEY ********\n +"; return "Can't proceed - no code for query $query\n"; } $sqlStatement = "update dataLoadProgress set progress = '" . $ +query . "'"; $sth = $dbh->prepare($sqlStatement) or return $DBI::errstr; $sth->execute() or return $DBI::errstr; } $sqlStatement = "update dataLoadProgress set progress = '" . $thin +gToDo . ":Success'"; $sth = $dbh->prepare($sqlStatement) or return $DBI::errstr; $sth->execute() or return $DBI::errstr; return "Success"; }
    This sub is kept in a '.pm' file which is called in a 'use' statement in the top-level script. If the top-level script is a command-line module, with no Tkx in it, the 'eval' works properly. If the top-level script has Tkx in it, it dies without going to the exception handler. I say this because the output from all those print statements is: 1 2 3 4 5 6 7 and the print statement in the error handler doesn't show The tkx code is extremely simple. Here it is:
    Tkx::package_require("style"); Tkx::style__use("as", -priority => 70); my $mw = Tkx::widget->new("."); $mw->g_wm_title("PSC Dataload"); $mw->g_wm_minsize(300,200); my $Email1; $Email1 = $mw->new_button( -text => "Email1", -command => [\&doTheWork,"Email1"], ); $Email1->g_pack(-padx=>10, -pady=>10,); my $Email2; $Email2 = $mw->new_button( -text => "Email2", -command => [\&doTheWork,"Email2"], ); $Email2->g_pack(-padx=>10, -pady=>10,); my $Email3; $Email3 = $mw->new_button( -text => "Email3", -command => [\&doTheWork,"Email3"], ); $Email3->g_pack(-padx=>10, -pady=>10,); my $Forms; $Forms = $mw->new_button( -text => "Forms", -command => [\&doTheWork,"Forms"], ); $Forms->g_pack(-padx=>10, -pady=>10,); my $LDG; $LDG = $mw->new_button( -text => "LDG", -command => [\&doTheWork,"LDG"], ); $LDG->g_pack(-padx=>10, -pady=>10,); my $Load; $Load = $mw->new_button( -text => "Do Data Load", -command => [\&doTheWork,"Load"], ); $Load->g_pack(-padx=>10, -pady=>10,); my $Log; $Log = $mw->new_button( -text => "Write Logs", -command => [\&doTheWork, "Logs"], ); $Log->g_pack(-padx=>10, -pady=>10,); $formalityList = $mw->new_button( -text => "Write Formality List", -command => \&writeFormalityList, ); $formalityList->g_pack(-padx=>10, -pady=>10,); my $b; $b = $mw->new_button( -text => "Exit", -command => sub { $b->m_configure( -text => "Bye Nora :\)", ); cleanUp(); Tkx::after(1500, sub {$mw->g_destroy; }); }, ); $b->g_pack(-padx=>10, -pady=>10,); Tkx::tk___messageBox( -parent => $mw, -icon => "info", -title => "Tip of the Day", -message => "Please be nice!", );
    Then there's some preliminaries and initialization, then
    #Start the GUI loop Tkx::MainLoop();
    If I remove that from the top-level program, the eval statement in the 'use' module works.

      My guess is, like shmem suspects, that you (or Tkx) are somewhere freeing up an object which uses eval in its destructor, which cleans out $@, so you never notice the exeption.

      Try::Tiny tries to prevent that, or you can code your eval like this:

      my $ok = eval { ... $sth->execute(); ... 1; }; if (! $ok) { print "Caught error: $@"; };