During an eval block, how do I trap errors originating only in that piece of code and not from some code that was called from withing that block? The following snippet can fail because $code_ref isn't defined/can't be looked up or because something inside $code_ref threw an error.

eval { $function_name->(); }; if ( my $e = $@ ) { # Just pretend that __FILE__ interpolates. if ( $e =~ /Undefined subroutine .+ called at if ( $e =~ /Unde +fined subroutine .+ called at __FILE__ line 2\./ ) { # Trap only this one error ... } else { # Rethrow the error die $e; } }

Perl only gives me a string to parse with a file and line number. Got a better way? Has anyone done anything nice with source filters or similar to tag the inside of eval blocks with #line "..." ... compiler directives to aid with the identification of errors from within specific blocks? There is a parallel problem of how to identify specific errors. I'm not as worried about that because that seems more tractable. The strings perl throws aren't as mutable or potentially strange as the file/line part I already identified; I can generally get away with expecting "Undefined subroutine" to remain constant.


Added: I am currently trying the following in AI::Prolog/Engine/Primitives.pm but it is ugly as sin and I don't want to have to do this in the general case.

use constant UNDEFINED_SUBROUTINE_ERROR => do { eval { no strict 'refs'; ## no critic NoStrict &{'---'}; }; my $e = $@; # Undefined subroutine &main::--- called at .../Primitives.pm line + 12. my ($msg) = $e =~ / \A (.+) # 'Undefined subroutine' (?<=\s) # ' ' \S* # &main:: ---/mx or die q[Perl's error message changed! Damn! Fix this regex.]; $msg; }; sub ... { ... # If the error is that I couldn't call the # function because it didn't exist or AUTOLOAD wouldn't DWIM then # I want to return fail. # # I want to avoid Class::Delegation's misfeature of eating all # non-related errors while it traps for the few things that it # needs. if ( my $e = $@ ) { # Extreme caution here. if ( $e =~ UNDEFINED_SUBROUTINE_ERROR ) { return FAIL; } elsif ( defined blessed $e ) { # Rethrow exception objects... die $e; } else { # Rethrow exception strings... if ( not $e = /\n\z/ ) { $e .= "\n"; } die $e; } } ... }

In reply to Trapping errors with specificity by diotalevi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.