When I attempt to run a command that does not exist using IPC::Open3::Simple a postgres database handle in the script gets closed.

The following code reproduces the problem. There are two $ipc->run lines. Comment one or the other out to see the different behaviour. There are several $dbh->ping lines used to narrow down where the connection was being dropped.
#! /usr/bin/perl -w use strict; use Data::Dumper; use DBD::Pg; use IPC::Open3::Simple; $| ++; my $DB_NAME = 'db_name'; my $DB_USERNAME = 'db_username'; my $DB_PASSWORD = '12345678'; # log in to the database my $dbh = DBI->connect("dbi:Pg:dbname=$DB_NAME", $DB_USERNAME, $DB_PASSWORD, ) or die $DBI::errstr; $dbh->trace(0); # now run a query to make sure the database connection works my $sth; unless ($sth = $dbh->prepare("select now()")) { warn "Unable to prepar +e SQL."; } unless ($sth->execute()) { warn "Unable to execute SQL."; } $sth->finish; print "ping " , __LINE__ , " " , $dbh->ping, "\n"; # now run a command that fails my (@cmd_output, @err_output); my $ipc = IPC::Open3::Simple->new( in => sub { my $fh = shift; print $fh "mydata"; close $fh; } , out => sub { push @cmd_output, $_[0]; } , err => sub { push @err_output, $_[0]; } , ); print "ping " , __LINE__ , " " , $dbh->ping, "\n"; #$ipc->run('date'); # this line is fine $ipc->run('no-such-command'); # this line causes the problem print "ping " , __LINE__ , " " , $dbh->ping, "\n"; print Dumper("output:", \@cmd_output, "error:", \@err_output), "\n"; print "ping " , __LINE__ , " " , $dbh->ping, "\n"; # now run another database query unless ($sth = $dbh->prepare("select now()")) { warn "Unable to prepar +e SQL."; } print "ping " , __LINE__ , " " , $dbh->ping, "\n"; unless ($sth->execute()) { warn "Unable to execute SQL."; } print "ping " , __LINE__ , " " , $dbh->ping, "\n"; $sth->finish; $dbh->disconnect() or die $DBI::errstr; exit 0;
The successful run looks like:
ping 30 1 ping 41 1 ping 46 1 $VAR1 = 'output:'; $VAR2 = [ 'Fri Apr 18 17:34:43 MDT 2008' ]; $VAR3 = 'error:'; $VAR4 = []; ping 50 1 ping 54 1 ping 56 1

The failing run looks like:
ping 30 1 ping 41 1 ping 46 0 $VAR1 = 'output:'; $VAR2 = []; $VAR3 = 'error:'; $VAR4 = [ 'Can\'t exec "no-such-command": No such file or directory at + /usr/lib/perl5/5.8.8/IPC/Open3.pm line 246.', 'open3: exec of no-such-command failed at /usr/lib/perl5/sit +e_perl/5.8.8/IPC/Open3/Simple.pm line 61' ]; ping 50 0 ping 54 0 DBD::Pg::st execute failed: no connection to the server at reproduce-c +rash.pl line 55. Unable to execute SQL. at reproduce-crash.pl line 55. ping 56 0

After working on it for a while I suspect the IPC::Open3::Simple code ends up doing something like the following:

* fork a child process. This process is a copy of the parent (ie it is a perl process).
* The child process tries to exec the command.
* The command does not exist so exec fails.
* The child perl process exits and closes the database handle it copied from the parent.

I am thinking of adding code to check to see that the first argument in the command to be executed is a readable, executable file.

Any other ideas of how to not have the database connection close?

Update: I should also mention there is nothing showing up in the postgres server log file (just autovacuum entries).

In reply to IPC::Open3::Simple closes database connection on error. by superfrink

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.