in reply to Re: eval failure does not set $@
in thread eval failure does not set $@

Only if the code you are executing "dies" or throws a warning, in the perl sense, would eval return something in $@.

But as I wrote, there are cases where the code in the eval can die, and $@ doesn't get set (Update: or to be more specific, gets clobbered so that it's no longer available after the eval). A simple demo of this bug:

use warnings; use strict; sub Foo::DESTROY { eval {} } eval { for (bless {}, "Foo") { print "Hello"; die "KABOOM"; } }; print "<$@>\n"; # Where's the kaboom? There was supposed # to be an earth-shattering kaboom!

Even on Perl 5.26, this only prints "Hello<>". That's why the eval { ...; 1 } or do { ... }; pattern is better - choroba showed how that pattern still works even in the presence of a similar bug on Perls <5.14 here.

If the routines you are running return a status, then you want to catch that status coming back from eval

I would suggest writing it this way, where of course 3+4 is a stand-in for something more complex (and it may also be a false value):

my $status; eval '$status = 3+4; 1' or warn $@||"unknown error";