Unexpected (?) try/catch Behavior

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
Disclaimer: I know enough Perl to get by when I absolutely have
to use it, so maybe this is the correct behavior, but having never
seen it in any other language, I thought I'd post the question to the
group and maybe learn something.

I have a scenario where I need to try to insert a record into a MySQL
database and, if the insert fails due to, well, anything, then perform
an update instead. To do this, I'm using the try/catch construct of
the Error module:

use Error qw(:try);

try {
       $sql = qq {
               INSERT INTO table (
               VALUES ( ?, ?, ?, ?, ? )

       $sth = $mysql->prepare ( $sql );
       $sth->execute ( $value1, $value2, $value3, $value4, $value5 );
catch Error with {
       $sql = qq {
               UPDATE table
                  SET field1      = ?,
                      field2           = ?,
                      field3               = ?
                WHERE field4             = ?
                      AND field5 = ?
       $sth = $mysql->prepare ( $sql );
       $sth->execute ( $value1, $value2, $value3, $value4, $value5 );

The code seems to be doing exactly what I expect. That is, dropping
into the catch block and performing the update where a record exists,
but the errors being caught are not being suppressed. I still get a
lot of:

DBD::mysql::st execute failed: Duplicate entry '121993-14196' for key
1 at ./get_metrics.pl line 247.

It's not the end of the world, but I'd prefer to suppress the message
if there's a way to do that. Is this expected behavior? It certainly
caught me by surprise and I spent a while trying to debug until I
realized that if I looked past the messages, the work was getting

I did try using the eval{} if ($@){} combo, but got the same result.


Re: Unexpected (?) try/catch Behavior

Rob Wilkerson wrote:
Quoted text here. Click to load it

Not answering your Perl question, but
what's wrong with:



Re: Unexpected (?) try/catch Behavior

Quoted text here. Click to load it

Hmmm. Nothing at all, except that I'd never needed it and wasn't aware
of its existence. I'll definitely look at that since it'd be a much
cleaner solution all the way around.

Thanks for the clue.

Re: Unexpected (?) try/catch Behavior

Quoted text here. Click to load it

So it turns out that I wasn't using this because it won't work (even
though I only figured that out now). The table I'm inserting/updating
has a dual primary key. That appears to be a no-no.

Re: Unexpected (?) try/catch Behavior

Quoted text here. Click to load it

Being in a try block does not prevent DBI from printing error
messages. You have to set the PrintError attribute on you database
handle to 'off'.


Re: Unexpected (?) try/catch Behavior

Quoted text here. Click to load it

Damn. I've built this thing to reuse a single database handle, so I
can't really do that. I might want those errors somewhere else.

Thanks for the insight.

Re: Unexpected (?) try/catch Behavior

Quoted text here. Click to load it
You can set the attribute anywhere you like. So you clear it to for
just the try block alone, and set it back to one afterward.

The other option is to clear PrintError and set RaiseError. That'll
make your script die on DBI errors unless you wrap your DBI method
calls in eval {} blocks. In case you want to continue on error, you
can just print the error message yourself.

I haven't used Error yet, so I don't know how it deals with DBI's


"We will need a longer wall when the revolution comes."
--- AJS, quoting an uncertain source.

Re: Unexpected (?) try/catch Behavior

First off, I don't agree with your tactic.  If you get a duplicate key
error, then by all means do an update instead if that is the logical thing
to do.  But if you get a "Server is currently on fire" error, I don't see
that going on to try to update is the right thing to do.

Quoted text here. Click to load it

Use local to localize the effect.

   local $mysql->=0;
   ## do whatever.  Errors will not be Printed
# at this point, PrintError has its original value.


-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Site Timeline