use Carp; sub sub1 { sub3(); sub2(); } # want the backtrace down to sub2 or sub3 sub sub2 { die "code failure"; } sub sub3 { die "runtime error" if rand() < 0.25 } sub main_sub { eval { #$dbh->begin_work; # various things, not all db-related sub1(); # more things #$dbh->commit; }; if ($@) { #$dbh->rollback; print STDERR $@; confess "the transaction failed"; }; } main_sub();