eval is not trapping the failed open3 call as you expect. Trim your code down to this:
[bmc@hacked lib]$ perl -MIPC::Open3 -e 'eval {$pid = open3(*IN, *OUT,
+*ERR, @ARGV);}; print "ACK $@\n" if ($@);' asdf
[bmc@hacked lib]$
Note that ack isn't printed.
eval is working as expected as you can see when you call the same code with no args:
[bmc@hacked lib]$ perl -MIPC::Open3 -e 'eval {$pid = open3(*IN, *OUT,
+*ERR, @ARGV);}; print "ACK $@\n" if ($@);'
ACK open3(*main::IN, *main::OUT, *main::ERR): not enough arguments at
+-e line 1
[bmc@hacked lib]$