do_a(); my::Error::register(\&undo_a, ARGS); if ($do_c) { do_c(); my::Error::register(\&undo_c, ARGS); } do_b(); my::Error::register(\&undo_b, ARGS); #### do_a(); register_err_handler(a => ARGS); if ($do_c) { do_c(); register_err_handler(c => ARGS); } do_b(); register_err_handler(b => ARGS); sub register_err_handler { my::Error::register( my::Plugin::ErrorHandler_->new(@_) ); } #### package my::Plugin::ErrorHandler; sub new { my $class = shift; my $handler = shift; return bless({ handler => $handler, args => [ @_ ] }, $class); } my %dispatch = ( a => \&my::Plugin::undo_a, b => \&my::Plugin::undo_b, c => \&my::Plugin::undo_c, ); sub handle_error { my ($self) = @_; $dispatch{ $self->{handler} }->(@{ $self->{args} }) } #### do_a(); my::Error::register(undo_a => ARGS); if ($do_c) { do_c(); my::Error::register(undo_c => ARGS); } do_b(); my::Error::register(undo_b => ARGS);