Trapping Errors with Eval

The end game of this task is to modify some MySQL based logging so it will try to connect to a central logging server, and if that fails, log to the local server, the update the central server when it can. We need this somewhat convoluted solution because MySQL does not support a many masters to single slave configuration. The current config uses an ‘or die’ when connecting to the MySQL server which basically means the whole process just crashes if the central MySQL server is having issues, which is not what we want.

The first test is looking at the eval function in Perl. Eval will allow us to trap errors and carry on with the rest of the script. The first illustration using a nice ‘divide by zero’ error is as follows:

#! /usr/bin/perl -w

use strict;
print "Nothing bad happens up to this point...\n";
my $badnumber = 4.5 / 0;
print "Our bad number is $badnumber\n";

When run produces:

Nothing bad happens up to this point...
Illegal division by zero at ./ line 5.

So if we wrap the 4.5 / 0 inside the eval tags, instead of just barfing, the the $badnumber is just undef and the code continues. This then produces other errors of the type:

Use of uninitialized value $badnumber in concatenation (.) or string at ./ line 7.

But the good news is that when the eval triggers an error the $@ scalar gets populated and we can use that to firstly show what the error was ($@ contains the error message), but then we can use its existence to set other things, in this case a default value for $badnumber. We are setting $badnumber to 1 on this occasion.

The last thing to note is that the curly brackets on eval must end in a semicolon because “eval is function, not a control structure” (see Alpaca book).

#! /usr/bin/perl -w

use strict;
print "Nothing bad happens up to this point...\n";
my $badnumber = eval{4.5 / 0};
if ($@) {
	print "Carrying on despite: $@";
	print "Setting \$badnumber to 1\n";
	$badnumber = 1;		
print "Our bad number is $badnumber\n";

The output is as follows:

Nothing bad happens up to this point...
Carrying on despite: Illegal division by zero at ./ line 7.
Setting $badnumber to 1
Our bad number is 1

That’s not the end of the story for our initial problem with MySQL, but an interesting ‘opening gambit’.

This entry was posted in Perl and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *