Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Try::Tiny catch block with $_ eq ''

by dd-b (Monk)
on May 16, 2013 at 21:12 UTC ( #1033905=perlquestion: print w/ replies, xml ) Need Help??
dd-b has asked for the wisdom of the Perl Monks concerning the following question:

I'm having trouble with ending up in my catch block without any indication of why. Code blocks like:

try { $self->_run($self, $row_id, $subject) } catch { $logger->error("run($row_id): $_\n") }; $self->_clear_subject;

(that $logger is from Log::Log4perl).

Something happens down in $self->_run() and I end up in the catch block, but with no indication of why.

So, what are the things that count as "errors" for Try::Tiny? The docs just say "error", which doesn't mean anything terribly precise. The obvious case I know about is die calls. I don't have any die calls with null strings as their arguments. (What I end up with in the catch block is a string that Data::Dumper prints as ''. I know that's not impossible; the error put in $_ may not be "true". But I don't have a die statement with a null string arg, and I wouldn't expect DBIC or any standard module to have a die call with a null string arg.)

I'm using DBIC database stuff in there, and I know it throws errors (in fact that's the point of this whole setup, to catch any errors it throws), but I don't expect it to throw null string errors; does it sometimes?

I may also be slightly wrong about how far my code got; I've run into at least one case (that I can't reproduce in a simple environment) where it seemed that $logger->trace("String with undefined $variable substituted"); would log nothing ($variable is undef; I'd expect it to log "String with undefined substituted" and give a warning on stderr about the undef, and that's what a simple program that does only that produces). Other trace level calls through the same $logger in the same module are logged. As I say, I can't reproduce this in a simple case, it may be another example of my getting confused.

Comment on Try::Tiny catch block with $_ eq ''
Select or Download Code
Replies are listed 'Best First'.
Re: Try::Tiny catch block with $_ eq ''
by tobyink (Abbot) on May 16, 2013 at 21:39 UTC

    The only "errors" that Try::Tiny cares about are die. (Though this also includes Carp::croak(), Carp::confess(), etc, because they call die internally.)

    The only way I can reproduce $_ eq "" is to call die($e) where $e is a blessed object with overloading, that overloads eq or "" to compare equal to the empty string.

    $ perl -MTry::Tiny -MData::Dumper -e'my $e = do { package E; use overl +oad q[""] => sub {""}, fallback=>1; bless [] }; try { die $e } catch +{ print Dumper($_ eq "") }'

    Update: oh yes; the other thing worth thinking about... are you using my $_ anywhere in this lexical scope? (Or given/when?) The lexical version of the $_ variable could be masking the global one (which is what Try::Tiny uses). Try starting your catch block with our $_; and see if that makes any difference.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      The "other ways to die" I know of, have checked for. I am not overloading eq or stringifiction, or throwing objects directly myself, in this code. I have no explicit my $_;. Hadn't thought about that (but would be unlikely to do it, too). However, there is given/when around some in this general area. I'll check the details of what that does. I don't think I'm inside it, though, so probably not the cause; but hadn't thought how that might interact, so I need to check. I don't think the catch blocks contain any given/when, though; still, I hadn't thought of that, need to check the possible cases, thanks!

Re: Try::Tiny catch block with $_ eq ''
by vsespb (Hermit) on May 16, 2013 at 21:29 UTC
    I don't know answer to your question, but you can try use perl 'sigtrap' module to get stacktrace, and possibly temporary replace try/catch/$_ with 'unless defined eval { }'/$@ , to debug your code.
    UPD: For example
    unless (defined eval { $self->_run($self, $row_id, $subject); 1 }) { $logger->error("run($row_id): $@\n") }; $self->_clear_subject;
    this way you'll check if that is the problem with "my $_" or no.

      I'm using Try::Tiny because they claim it's hard to really use eval correctly to do this, but I could switch back and hope I don't hit their problem cases, at least as a test. We shall see. I've been putting eleventy-dozen $logger->trace("point 17"); statements through the code it comes out of unexpectedly to narrow down where it is. Setting up the database for a test run and then analyzing the log is not as simple as I could hope it was (though far better than my test setup procedure two weeks ago :-) ).

        I think it's hard when there are nested evals. Otherwise it's pretty simple, if you read the docs carefully.
Re: Try::Tiny catch block with $_ eq ''
by sundialsvc4 (Abbot) on May 17, 2013 at 13:32 UTC

    What I prefer to use is Exception::Class, in conjunction with Try::Tiny.   You can die (that is, “throw an error”) with an object as well as with a string, and this gives you a well-defined way to communicate between the point of the error and its ultimate handler.   (Wrap “legacy code” sections in a handler that catches the (string ...) exceptions and throws an object containing, among other things, that string.)

    An exception class can not only carry any sort of a “payload” (including undef values as-needed), but it is also self-identifying you have not only the class-name but the entire class hierarchy that you’ve cooked up.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1033905]
Approved by ww
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (10)
As of 2015-07-30 23:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls