And a test script:use strict; use warnings; use base qw( Exporter ); use B::Deparse; use Data::Dumper; our @EXPORT = qw( local_eval ); # # Use the & prototype to convert the {} block into a coderef # sub local_eval(&) { my $code = shift; my ($pkg,$file,$line) = caller(); my $context = find_context($code); print Dumper($context); eval { $code->(@_); }; if ($@) { my $exception = $@; # This will only work if the error contains something like thi +s: # "at local_err.pl line 36." my ($err_file,$err_line) = $exception =~ /at (.*?) line (\d+)/ +; if ($context->{$err_file}{$err_line}) { # Make sure $@ was not changed locally. $@ = $exception; return; } else { # Rethrow the exception die $exception; }; } } # # Deparse the passed codeblock, stripping out the file names and # line numbers provided by the '-l' option. sub find_context { my $code = shift; my $deparse = B::Deparse->new('-p','-l','-sC'); my $src = $deparse->coderef2text($code); #Expects things like: line 31 "local_err.pl" my @lines = $src =~ /^#line (\d+ ".*")$/mg; my %context = (); for my $entry (@lines) { my ($line,$file) = split / /,$entry,2; $file =~ s/^"|"$//g; $context{$file}{$line}++; } return \%context; } 1;
It's not 100% reliable, but it might be an avenue to explore. If I have time later I'll play with it some more. Update - I haven't played with B::Deparse enough to know what the pitfalls are. Will write a test suite this evening or tomorrow to try and identify shortcomings.use strict; use warnings; use LocalEval; local_eval { print "hello\n"; splode(); }; print "Should still run.\n";
In reply to Re: Trapping errors with specificity - LocalEval
by imp
in thread Trapping errors with specificity
by diotalevi
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |