Automatically rethrowing (die $@) prevents you from catching several different types of exceptions in a series of elsifs -- I think you probably only want to rethrow if none of your catches match:
if ( eval ... ) {
...
} elsif ( catch("E") ) {
...
} elsif ( catch("F") ) {
...
} else {
die $@;
}