views:

157

answers:

3

I have a simple Perl script which runs as a Linux daemon using an infinite loop. It connects to a database every 10 seconds to execute a process.

while (1)
{
    # THIS LINE WILL KILL THE SCRIPT IF IT FAILS
    my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password");
    . . . do something . . .
    sleep (10);
}

I have two questions:

  • If the DB is unavailable, how I can keep the script running?
  • Can I add an exception handler to send me an email or log an error?
+8  A: 

This attempts to connect at 10 second intervals, not every 10 seconds, as William Pursell noted:

while (1)
{
    # THIS LINE WILL KILL THE SCRIPT IF IT FAILS
    my $DB;
    eval { 
        $DB = DBI->connect("dbi:Sybase:server=myserver","user","password");
    };
    if ( my $ex = $@ ) {
        warn $ex;
        next;
    }
    # do something with $DB
    continue {
        sleep 10;
    }
}

See also Object Oriented Exception Handling in Perl, is it worth it? and How can I cleanly handle error checking in Perl?

Sinan Ünür
I don't think you want to redeclare my $DB inside the eval block.
xcramps
@xcramps Thank you for noticing and letting me know.
Sinan Ünür
+1  A: 

From Programming Perl:

sub try (&@) {
     my($try,$catch) = @_;
     eval { &$try };
     if ($@) {
         local $_ = $@;
         &$catch;
     }
}
sub catch (&) { $_[0] }

try {
    die "phooey";
} catch {
    /phooey/ and print "unphooey\n";
};
William Pursell
+5  A: 

I'm a bit puzzled:

   my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password");

should not normally die if it can't connect. Normally it should return an Error Code instead of a db-handle. Only if you use RaisError will it die / throw an exception.

   my $DB=DBI->connect("dbi:Sybase:server=myserver","user","password", 
                        { RaiseError => 1});

See the DBI man-page

bjelli