# called just after an eval sub catch { # don't catch if no error return 0 unless defined $@; # checks if $@->isa(one of the type in @_); UNIVERSAL::isa($@,$_) && return 1 for @_; # otherwise re-throws die $@; } # later on ... while (my ($name,$val) = each %input) { if(eval { validate($val) }) { $session->set($name, $val); } elsif(catch('ARRAY','E')) { $errors{$name} = $@; $action = 'reshow'; } } # ... eval { $nav->$action() } or catch('E::Nav') and do { $error = $@; $nav->reshow }; # ... other things I haven't thought of ...